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
