I have finally got the webserver to work. Unsurprisingly there were NO bugs in any of the C++ library code!
The problem was Felix's aggressive inlining, i.e. in the compiler! Felix is VERY efficient at replacing variables with values. Too efficient! Consider the webserver loop: forever { var s: socket_t; dbg$ "Waiting for connection\n"; accept(listener, &s); // blocking dbg$ "got connection "+str s + "\n"; // error check here print$ "spawning fthread to handle connection "+str s+"\n"; var h = handler s; spawn_fthread h; }; and the handler code: proc handler (var k:socket_t) () { dbg$ "Spawned fthread running for socket "+str k+"\n"; .... fprint$ cerr,"fthread closing socket "+str k+"\n"; Faio::sleep(clock,5.0); ioclose(k); fprint$ cerr,"fthread "+str k+" terminating!\n"; }; What I noticed was that two fthreads would be spawned ok when I did two requests on the webserver .. but it appeared the same fthread terminated twice... Actually no, Felix is so dang good at inlining, the handler argument k got replaced in the closure h by a reference to the variable s, instead of being copied! Heck, I put in the "var k" there to stop that, but it didn't work. The problem is that whilst handler (s) () is not inlined .. handler(s) . I fixed the bug by simply saying: noinline proc handler (var k:socket_t) () Did you follow all that? No? Me either :) In this case a simple work-around would have been to write the correct code and use a channel to send the fthread the socket. But in other cases where you want to form a closure and bind an argument into it via a parameter, then change the argument in a loop, and repeat, you will come to the same grief. The problem is when you make a closure by a partial call, you actually have: proc handler (k:socket_t) { proc inner () { fprint$ cerr,"Spawn " + str k; } return inner; } If THIS procedure is inlined, as in: h = handler (s); you actually get: h = inner [ with k replaced by s ]; in other words, h is inner referring to the current value of the top level variable s, not the value s had at the time the closure is formed. I'm not sure why using "var k:socket_t" as the parameter didn't stop this, but probably it is because this merely forces eager evaluation for handler, not for "inner", and even variable uses get replaced by their values if Felix detects they are only assigned once. That really is the bug. Felix isn't noticing variables are assigned more than once if they're inside a loop. AFAIK this never happens if you use tail recursion instead of a loop.. but Felix has goto anyhow, so it's no excuse :) RF also ran into this problem with closures. Felix, unlike C++ prefers replacement to copying, which is equivalent to passing an address .. the problem is it just isn't obvious where and when this happens and how to work around the fact it is almost impossible in Felix to actually force a value to be copied (short of cheating, and using an identity() function written in C). Hmm .. actually that's not a bad idea but it probably wouldn't work, because you still have to copy the value at the right time! Well.. As I have noted previously turning off optimisations such as those responsible for this problem is NOT an option. Vastly too much code is generated on the assumption inefficiencies can and will be optimised away. The problem is to detect when code is inside some kind of loop. On way to fix this is to rewrite the compiler to use continuation passing. For example loops become tail recursions, and gotos tail calls. I suggest this because I think Felix handles functional code correctly .. as usual, variables are the problem. -- john skaller skal...@users.sourceforge.net ------------------------------------------------------------------------------ Beautiful is writing same markup. Internet Explorer 9 supports standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3. Spend less time writing and rewriting code and more time creating great experiences on the web. Be a part of the beta today. http://p.sf.net/sfu/beautyoftheweb _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language