4

In this example, I am simply printing the numbers from 0 to 9 with a delay after each. However, instead of trickling the numbers to the output window, there is a long pause (with a "spinner" icon churning) and then all of the numbers are displayed at once (tested in both Chromium 44.0 and Firefox 40.0.3).

Is there a way to to make writes to stdout display immediately?

#include <stdio.h>

void time_waster( int reps=100 ) {
   static volatile unsigned counter=0;
   for ( int a=0; a<reps; a++ ) {
      for ( int b=0; b<1000*1000; b++ ) counter++;
   }
}

int main() {
  for ( int i=0; i<10; i++ ) {
     fprintf(stdout,"%d\n",i);
     fflush(stdout);
     time_waster();
  }
}

JavaScript and HTML built with:

emcc -Wall -Werror -o temp.html count.c

By the way, the combined size of the generated HTML+JavaScript for this small example is roughly 600KB (14619 lines), so debugging in the browser would be a non-trivial task.

Note: I had the same issue with std::cout in C++ (also with explicit flushing), but decided to write the question in C as a simplification of the problem.


I have discovered that the output is displayed as intended if I run the program with node.js:

node temp.js

So the problem only occurs when running in a browser using the HTML generated by the Emscripten compiler.

Brent Bradburn
  • 51,587
  • 17
  • 154
  • 173

2 Answers2

3

From the emscripten source we find that fflush does nothing.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • 1
    +1 for the good data. However, there seems to be some ambiguity in the linked pages about whether or not the no-op `fflush()` is relevant in the case where the strings include `\n` (as mine do). In other words, `stdout` might/should be "line-buffered" as described [here](http://stackoverflow.com/questions/3723795/is-stdout-line-buffered-unbuffered-or-indeterminate-by-default), and therefore each line should appear immediately, regardless of `fflush()`. I really only added the `fflush()` to prevent commenters from suggesting it. – Brent Bradburn Sep 14 '15 at 21:13
2

Perhaps that behavior is by design, thus the main loop needs to be replaced by emscripten_set_main_loop or Emterpreter-Async.

https://github.com/kripken/emscripten/wiki/Emterpreter

#include <stdio.h>
#include <emscripten/emscripten.h>

void time_waster( int reps=100 ) {
   static volatile unsigned counter=0;
   for ( int a=0; a<reps; a++ ) {
      for ( int b=0; b<1000*1000; b++ ) counter++;
   }
}

int main() {
  for ( int i=0; i<10; i++ ) {
     fprintf(stdout,"%d\n",i);
     fflush(stdout);
     emscripten_sleep(0);
     time_waster();
  }
}

em++ -Wall -Werror -o temp.html count.cpp -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1 -s EMTERPRETIFY_WHITELIST="['_main']" -Oz

zakki
  • 2,283
  • 14
  • 20
  • This solves the problem. Note: [You need a web server to run it](http://stackoverflow.com/questions/10752055/cross-origin-requests-are-only-supported-for-http-error-when-loading-a-local). – Brent Bradburn Sep 15 '15 at 16:43