Le 11/11/12 10:03 AM, Julien Vermillard a écrit :
> when the I/O selector code :
>  - queue.isEmpty() ?
>  - set write flag off
>
> write thread code :
>  - queue.add(message)
>  - set write flag on

Thanks for the heads up.

I had in mind the fact that the write thread queue should not set the
flag. The selector thread should instead set the flag when the queue is
not empty. The only thing the write thread queue should do is to wake up
the selector when it pushes some message in the queue.

Doing so remove all the potential concurrency issue, but it has a few
drawbacks (see below)

We can see the time line for such operations :

T0 : selector thread select() is waked up because a read event occured.
T1 : the selector thread call the messageReceived() event
T2 : the selector thread goes to sleep (no more event to proceed) | T2 :
the session thread processes the messageReceived() event
T3 : the selector thread still sleeps | T3 : the session thread write
some message, push it into the write queue, and wakeup the selector thread
T4 : the selector thread is awakened, sees that there is some messages
to write in the queue, try to write them and if it can't write them all,
set the OP_WRITE event

That should work. The only problem here is to know which writeQueue to
check.

Now, I can see how such a scenario can be seen as not perfect : though
it get rid of any concurrency issue, it forces the selector thread to
either check all the sessions to see if there is some messages in their
writeQueue (that assumes we have one writeQueue per session) *or* we use
one single writeQueue for *all* the sessions, and we don't have any
problem at all, except that we will have to process all the messages in
this queue, and not the first ones -not an ideal scenario, as we will
have many messages blocked, and this would require some huge
modification in the queue-.

So maybe my scenario is not perfect... Maybe we should let the write
thread set the OP_WRITE flag, but I don't know if this is possible when
the select() is blocked ?

One other possible option would be to have a second queue
-writingSessionQueue- (this queue would be shared between the selector
thread and the writer threads), containing the sessions that have
written something in their message queue. Doing so, the Selector thread
would check this queue, and for each session, will try to write the
pending messages, thus setting the OP_WRITE itself.

This third option is probably the best I can foresee, and it does not
need any other lock than the one provided by the writingSessionQueue.

wdyt ?



Second point : by-passing the writequeue
In most of the case, we won't have any pending message (or partial
message) waiting for the socket to be ready for write, and then, we
should be able to write directly into the socket, without having to push
the message into a queue. That means the session thread should be able
to write into the channel, and if the message can't be written
completely, then push it into the writeQueue.


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com 

Reply via email to