On Mon, 4 Apr 2011 20:23:43 +0200, Adam Lackorzynski wrote:
On Sat Apr 02, 2011 at 12:58:34 +1300, Valery V. Sedletski wrote:
....
I feel that these problems have common solutions, but i'm in trouble -- maybe, someone will help with finding these common solutions?
I think the generic solution is to maintain a couple of worker threads inside the server and delegate work to them, keeping the main server thread responsive. Another solution could be to have a thread per client.
So, I could imagine, that the server thread, when receiving a message from a client, starts a child, then sends a message to one of its worker threads, then it blocks on a semaphore (which is local to the server). Then the server loop must continue, but not respond to the 1st client (which started the 2nd task) until the worker thread unblocks. -- The worker thread unblocks, and answers to the 1st client (which has been blocked), then it continues.
But how can I tell DICE to not immediately answer the 1st task? -- I checked my IDL methods, and see one of them having the
short *dice_reply;
parameter. -- I found that if it is equal to DICE_REPLY, then the server loop calls marshal function and replies to the client. But if it is equal to the DICE_NEVER_REPLY, then it doesn't reply. -- Maybe, I can use this feature, but how to force DICE to generate such a parameter? -- My other IDL methods haven't one... Can I specify some attribute to the method?
On Mon Apr 04, 2011 at 09:22:07 +1300, Valery V. Sedletski wrote:
On Sat, 02 Apr 2011 12:58:34 +1300 (MSD), Valery V. Sedletski wrote:
Hi all.
...
I have rethought the problem and, it seems, found the solution -- still block on a semaphore, but not in server stub, but in the client routine which calls the RPC to the server.
But the problem remains -- the semaphore is in the server, but need to share it with the client for it to reset it. -- So the next question arises -- how to tell DICE to map the semaphore to the client? -- I have the semaphore in the server, and trying to return it from the RPC to the server. But DICE returns a copy of the semaphore, and not maps it to the client. I try to use the following IDL declaration:
APIRET dos_ExecPgm ([out, string, prealloc_client, prealloc_server] char **pObjname, [in] long cbObjname, [in] unsigned long execFlag, [in, string] char *pArg, [in, string] char *pEnv, [in, out] struct _RESULTCODES *pRes, [out, size_is(len), ref, prealloc_client, prealloc_server] l4semaphore_t **tSem, [out] int *len, [in, string] char *pName);
-- so, I'm trying to use 'ref' attribute for tSem. But in that case, DICE requires me to specify the array with 'len' parameter. Can I avoid this length parameter? (I must return one l4semaphore_t * value from the IDL method, and get the mapping of original semaphore, not its copy).
I think the l4semaphore was never intented to be used between two different tasks. Also, if you would do so, l4semaphore_t must be in shared memory between the two tasks, as the structure is for example maintaining a counter that is used in the up and down implementations. Thus you'd need to map the memory to the task, and have it placed on a separate page.
I supposed that DICE can establish a temporary shared memory area around the semaphore, and the counters will update accordingly. (I used 'ref' attribute beside the semaphore).
I guess in your situation blocking on a worker thread in server could work.
But the situation 'out of worker threads' can occur, so 'Denial of service' can occur. -- I heard, L4 has a limitation of 127 threads per task, is it true?
WBR, valery