does a simple lock on a quickly unlock resource between two thread is really an issue ? sometimes a lock or a spin lock is much more efficient than message passing around and thread wakeuping (context switching).
I think we should keep the lock and focus on the queue bypassing which is probably a high gain. On Sun, Nov 11, 2012 at 10:27 AM, Emmanuel Lécharny <[email protected]>wrote: > 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 > >
