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

Reply via email to