MOO-Cows

moo-cows Topic: Threaded processes in the server?

Article #1101
Subject: Threaded processes in the server?
Author: Mark O'Neil
Posted: 4/3/2001 07:16:33 AM

Okay.

I need some clarification before I undertake something.

When running a MOO 'core-verb' such as Fireplace where it sleeps,
periodically waking up to display any Fireplace messages, my understanding
is that when the server processes tasks it bypasses sleeping tasks. I recall
that Fireplace is forked. I assume this works the same if the verb is not
forked?

Another scenario: the configure verb: it pauses while waiting for input from
the user. Again the server ignores the task unless input has been provided.

???

Here is what I want to do:

Currently my Authentication additions block the server until the
Authentication process is complete. What I want to do is thread the
Authentication process so that I can call from a verb in-MOO the
Authenticate built-in which spawns an authenticate thread (Auth_thread) and
returns a result signifying success of thread startup, the calling routine
then sleeps and wakes every few seconds (until max wait) and checks (via
another built-in Auth_check) for the completion of the Auth_thread. This
check would be non-blocking. Meanwhile the Auth_thread runs the
authentication. After either a failure or the passing of max_wait the
Auth_check returns failure.

The thread starter starts the thread and returns (no block) the thread isn't
attached to the server tasks, the Auth_check is in and out checking for a
success flag (perhaps on the nhandle), the MOO verb caller hangs around
waiting for success or times out.

The bottom line is all that gets 'blocked' here is the verb that is
performing the initial sleep/wake call - correct?

Opinions desired....

regards,
-m


Responses:

Article #1102
Subject: Re: Threaded processes in the server?
Author: clharada
Posted: 4/3/2001 07:32:45 AM

I think you can try see the login procedures.
I think you can do what you want without the sleep / wake / check loop,
implementing a kind of callback method.
Look, I'm not saying to use an assynchronous callback. Just use the same
idea of the login procedure (I don't know how it works but I know that it
can start a new moo-task when a connection arrives).




On Tue, 3 Apr 2001, Mark O'Neil wrote:

> Okay.
>
> I need some clarification before I undertake something.
>
> When running a MOO 'core-verb' such as Fireplace where it sleeps,
> periodically waking up to display any Fireplace messages, my understanding
> is that when the server processes tasks it bypasses sleeping tasks. I recall
> that Fireplace is forked. I assume this works the same if the verb is not
> forked?
>
> Another scenario: the configure verb: it pauses while waiting for input from
> the user. Again the server ignores the task unless input has been provided.
>
> ???
>
> Here is what I want to do:
>
> Currently my Authentication additions block the server until the
> Authentication process is complete. What I want to do is thread the
> Authentication process so that I can call from a verb in-MOO the
> Authenticate built-in which spawns an authenticate thread (Auth_thread) and
> returns a result signifying success of thread startup, the calling routine
> then sleeps and wakes every few seconds (until max wait) and checks (via
> another built-in Auth_check) for the completion of the Auth_thread. This
> check would be non-blocking. Meanwhile the Auth_thread runs the
> authentication. After either a failure or the passing of max_wait the
> Auth_check returns failure.
>
> The thread starter starts the thread and returns (no block) the thread isn't
> attached to the server tasks, the Auth_check is in and out checking for a
> success flag (perhaps on the nhandle), the MOO verb caller hangs around
> waiting for success or times out.
>
> The bottom line is all that gets 'blocked' here is the verb that is
> performing the initial sleep/wake call - correct?
>
> Opinions desired....
>
> regards,
> -m
>


Article #1103
Subject: Re: Threaded processes in the server?
Author: Jeff Dubrule
Posted: 4/3/2001 08:17:34 AM

On Tue, Apr 03, 2001 at 08:16:33AM -0400, Mark O'Neil wrote:
> Here is what I want to do:
>
> Currently my Authentication additions block the server until the
> Authentication process is complete. What I want to do is thread the
> Authentication process so that I can call from a verb in-MOO the
> Authenticate built-in which spawns an authenticate thread (Auth_thread) and
> returns a result signifying success of thread startup, the calling routine
> then sleeps and wakes every few seconds (until max wait) and checks (via
> another built-in Auth_check) for the completion of the Auth_thread. This
> check would be non-blocking. Meanwhile the Auth_thread runs the
> authentication. After either a failure or the passing of max_wait the
> Auth_check returns failure.
>
> The thread starter starts the thread and returns (no block) the thread isn't
> attached to the server tasks, the Auth_check is in and out checking for a
> success flag (perhaps on the nhandle), the MOO verb caller hangs around
> waiting for success or times out.

You would have to set up a system similar to a reading task in the
server to deal with this.  The server does not use POSIX threads or
any other form of OS-assisted threading to provide the
cooperative-multithreaded core environment.

Reading tasks work by polling the connection to see if it is finished
reading every time through the scheduler, and, when it is finished,
resuming the reading VM.

To do this with the Authentication server, you'd have to have a
non-blocking wait[3-4]() call every time through the run_ready_tasks
loop in tasks.c, which would see if the thread you started was
complete and, if so, would retrieve & return the answer.

The other option might be to use popen() to open a socketed connection
to an external command, or to build a separate daemon (perhaps as a
PHP/Python/CGI script) and open_network_connection() it.

-manta


Article #1105
Subject: Re: Threaded processes in the server?
Author: Mark O'Neil
Posted: 4/3/2001 10:29:44 AM

on 4/3/01 9:17 AM, Jeff Dubrule at igor@nospam wrote:

Hello Jeff,

> You would have to set up a system similar to a reading task in the
> server to deal with this.  The server does not use POSIX threads or
> any other form of OS-assisted threading to provide the
> cooperative-multithreaded core environment.

Granted the server is not built around any form of threading and personally
I have not written any threaded C code [yet - Java no problem (C:]. I was
told by someone here who works with threaded C code that I could add the use
of POSIX threads rather easily(?), hence my direction for this task.

> Reading tasks work by polling the connection to see if it is finished
> reading every time through the scheduler, and, when it is finished,
> resuming the reading VM.

Yes. VM?

> To do this with the Authentication server, you'd have to have a
> non-blocking wait[3-4]() call every time through the run_ready_tasks
> loop in tasks.c, which would see if the thread you started was
> complete and, if so, would retrieve & return the answer.

Back on POSIX right?

Using the above in lieu of a second bf_ which would check for completion or
perhaps I am confused by exactly how wait would work. (do you mean to place
the equiv. of the second bf_ in as the wait?) The first bf_ which starts the
thread must return in order to not block the server correct? How then on the
MOO side (where the auth request began) would I wait for the results passed
by the non-blocking wait call in tasks.c unless I had a second built-in to
ask for them? and if I have the second bf_ to ask for them do I need the
wait at all?

I was going to add a linked list of aRequest structure {playerID, results}
pointers which would be set by the thread and use a second bf_ to check the
status.

Authentication would be called as a MOO-task:
tm = 0;
results = 0;
results = authentication_check(start_authentication(player), player);
"start_authentication(player) => thread starter";
"authentication_check(thread_started, playerID) => thread check";
while (results == 0)
    suspend(2);
    tm = tm+2;
    if (tm==60)
        break;
    endif
    results = authentication_check(1, player);
endwhile

If results == 0 then authentication failed otherwise analyze the results.

Currently I use something like:
if (authenticated(player))....


> The other option might be to use popen() to open a socketed connection
> to an external command, or to build a separate daemon (perhaps as a
> PHP/Python/CGI script) and open_network_connection() it.

It just seems simpler (less bits to break) in the long run to not rely on
external processes which is why I have been trying to avoid them and
focusing on a in-server solution.

regards,
-m


Article #1106
Subject: Re: Threaded processes in the server?
Author: manta
Posted: 4/3/2001 12:43:10 PM

On Tue, Apr 03, 2001 at 10:58:07AM -0400, Mark O'Neil wrote:
>
> > Reading tasks work by polling the connection to see if it is finished
> > reading every time through the scheduler, and, when it is finished,
> > resuming the reading VM.
>
> Yes. VM?

VM = Virtual machine.  The MOO executes code by compiling it into
bytecodes, then these get executed by a Virtual Machine.  This allows
us to stop a task and resume it with no problem.

> > To do this with the Authentication server, you'd have to have a
> > non-blocking wait[3-4]() call every time through the run_ready_tasks
> > loop in tasks.c, which would see if the thread you started was
> > complete and, if so, would retrieve & return the answer.
>
> Back on POSIX right?
>
> Using the above in lieu of a second bf_ which would check for completion or
> perhaps I am confused by exactly how wait would work. (do you mean to place
> the equiv. of the second bf_ in as the wait?) The first bf_ which starts the
> thread must return in order to not block the server correct?

No.  The bf_ should act like the read() builtin turning the task into
a reading task.  Then, in run_ready_tasks(), which is the function
which handles choosing which task gets to run next, you'd have a
section to check whether the authenticate finished, and, if so, brings
it back, and the bf_ returns.

-jeff


Article #1104
Subject: Re: Threaded processes in the server?
Author: Mark O'Neil
Posted: 4/3/2001 01:00:28 PM

on 4/3/01 1:43 PM, manta at manta@nospam wrote:

> VM = Virtual machine.  The MOO executes code by compiling it into
> bytecodes, then these get executed by a Virtual Machine.  This allows
> us to stop a task and resume it with no problem.

Never thought of the MOO server as a VM. (C;
Okay.

> No.  The bf_ should act like the read() builtin turning the task into
> a reading task.  Then, in run_ready_tasks(), which is the function
> which handles choosing which task gets to run next, you'd have a
> section to check whether the authenticate finished, and, if so, brings
> it back, and the bf_ returns.

Ah gotcha. No nasty POSIX thread bits, just difficult/stubborn cows!

Off to read up on Read() and run_ready_tasks().

-m


Article #1107
Subject: Re: Threaded processes in the server?
Author: Andrew Wendt
Posted: 4/4/2001 05:53:59 PM

> > No.  The bf_ should act like the read() builtin turning the task into
> > a reading task.  Then, in run_ready_tasks(), which is the function
> > which handles choosing which task gets to run next, you'd have a
> > section to check whether the authenticate finished, and, if so, brings
> > it back, and the bf_ returns.
>
> Ah gotcha. No nasty POSIX thread bits, just difficult/stubborn cows!
>
> Off to read up on Read() and run_ready_tasks().

You might want to look at the #ifdef'd out bf_read_stdin and friends at the
top of extensions.c too.

I think it's pretty much an example of how to do exactly what you want, and I
don't think it would require changing things like run_ready_tasks().

TTFN
Andy



MOO-Cows Home