<br><font size=2 face="sans-serif">Well I would certainly agree that a
blocking queue should only be used where a blocking queue is appropriate.
But given that proviso, then when it is used, the behavior we're talking
about here is the correct one. If you want to be able to peek, the GetQueueArray
method attempts to satsify that need. If you cactually want to take an
element, if one is there, and return otherwise, then a non-blocking dequeue
could be provided, but that would beg the question why it should be necessary
to defeat the monitor's queuing mechanism in this way and it's use should
be very carefully administered.</font>
<br>
<br><font size=2 face="sans-serif">We could add a boolean to dequeue indicating
whether or not the thread is willing to wait; but choosing which call to
make has to remain the responsibility of the programmer. Choosing the wrong
one is an error of design, not a fault in the notion of blocking queues.</font>
<br>
<br><font size=2 face="sans-serif">If you want REALLY hard problems to
debug, then incorporating mechanisms intended to accomodate programmer's
mistakes is definitely the way to go. :-)</font>
<br><font size=2 face="sans-serif"><br>
Best regards<br>
Alan<br>
-------------------<br>
T.J. Watson Research Center, Hawthorne, NY<br>
1-914-784-7286<br>
alan_webb@us.ibm.com</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>Stefan Andersson <stefan@tribalmedia.se></b>
</font>
<br><font size=1 face="sans-serif">Sent by: opensim-dev-bounces@lists.berlios.de</font>
<p><font size=1 face="sans-serif">03/26/2008 11:25 AM</font>
<table border>
<tr valign=top>
<td bgcolor=white>
<div align=center><font size=1 face="sans-serif">Please respond to<br>
opensim-dev@lists.berlios.de</font></div></table>
<br>
<td width=59%>
<table width=100%>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td><font size=1 face="sans-serif"><opensim-dev@lists.berlios.de></font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td><font size=1 face="sans-serif">Re: [Opensim-dev] BlockingQueue</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><font size=2 face="Tahoma">This is all true. What CAN and HAVE happened,
is that somebody not aware that a method calls a method that calls a method
that reads from the Blocking Queue suddenly finds herself waiting for somebody
else to put an item into the queue. This kind of thread interdependency
can lead to VERY hard-to-debug scenarios.<br>
<br>
Which, incidentally, gets even worse since it's only one thread that is
released at a time.<br>
<br>
/Stefan<br>
<br>
<br>
<br>
</font>
<br>
<hr><font size=2 face="Tahoma">To: opensim-dev@lists.berlios.de<br>
From: alan_webb@us.ibm.com<br>
Date: Wed, 26 Mar 2008 11:03:21 -0400<br>
Subject: Re: [Opensim-dev] BlockingQueue<br>
<br>
</font><font size=2 face="sans-serif"><br>
The BlockingQueue uses Monitor.Pulse which only releases ONE thread for
execution. The others remain suspended. PulseAll is needed if you want
to awaken all the waiting threads. So the race condition that you describe
should not happen (if Mono corrcetly implements Monitor anway).</font><font size=2 face="Tahoma">
<br>
</font><font size=2 face="sans-serif"><br>
The queue AND the lock are private to the BlockingQueue class, so the only
unsynchronized mechanism for examining the queue is GetQueueArray
which returns a copy of the content. In principle It isn't possible for
anyone to damage the queue. The lock cannot be obtained by anyone not using
the proper BlockingQueue accessors.</font><font size=2 face="Tahoma"> </font><font size=2 face="sans-serif"><br>
<br>
Best regards<br>
Alan<br>
-------------------<br>
T.J. Watson Research Center, Hawthorne, NY<br>
1-914-784-7286<br>
alan_webb@us.ibm.com</font><font size=2 face="Tahoma"> <br>
<br>
</font>
<table width=100%>
<tr valign=top>
<td width=62%><font size=1 face="sans-serif"><b>Justin Clark-Casey <jjustincc@googlemail.com></b>
<br>
Sent by: opensim-dev-bounces@lists.berlios.de</font><font size=3 face="Tahoma">
</font><font size=1 face="sans-serif">03/26/2008 10:43 AM</font><font size=3 face="Tahoma">
</font>
<br>
<table border=4 width=100%>
<tr valign=top>
<td width=100% bgcolor=white>
<div align=center><font size=1 face="sans-serif">Please respond to<br>
opensim-dev@lists.berlios.de</font></div></table>
<br><font size=3 face="Tahoma"><br>
</font>
<td width=37%>
<table width=100%>
<tr valign=top>
<td width=18%>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td width=81%><font size=1 face="sans-serif">opensim-dev@lists.berlios.de</font><font size=3 face="Tahoma">
</font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td><font size=1 face="sans-serif">Re: [Opensim-dev] BlockingQueue</font></table>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=50%>
<td width=50%></table>
<br></table>
<br><font size=2 face="Tahoma"><br>
<br>
<br>
Stefan Andersson wrote:<br>
><br>
> > > Preparing for the bug-a-thon friday, I want us to come together
on <br>
> how<br>
> > > we will write this out of the core; I think it will give
us much<br>
> > > better control over threading and deadlocking.<br>
> > For people relatively new to the project, could you give any
<br>
> examples of<br>
> > particular problems here?<br>
><br>
> Well, the thing with the BlockingQueue is that it functions this way:<br>
><br>
> if something _Reads_ the queue, and it happens to be empty, the thread
<br>
> is BLOCKED until something else _Adds_ to the queue. Of course, if
<br>
> another thread comes along and reads from it, it is blocked as well,
<br>
> and all of them are released in one merry explosion when an item is
<br>
> Added. Which probably leads to all kinds of weird race conditions.<br>
That was my reading of it. At least in the case of assets, there's
only <br>
one thread which actually reads the blocking queue atm (AssetCacheThread).<br>
> <br>
> > ><br>
> > > (The PROBLEM with the BlockingQueue is that threads might
LOCK<br>
> > > unknowingly because a sub-call felt like taking a peek at
some<br>
> > > blocking queue. Really really bad form.)<br>
> > Could you be more specific? Looking at OpenSim.Framework.BlockingQueue,<br>
> > I can't see where deadlock could occur - none of the methods
hold on to<br>
> > the m_queueSync lock for long. However, I'm relatively new to<br>
> > synchronization in dot net, though I have done some in Java -
I <br>
> could be<br>
> > missing something.<br>
><br>
> I don't mean deadlock as in ordinary lock{ } constructs, I mean the
<br>
> use of mutexes can cause a 'wrong' thread to lock by (coder) mistake.
<br>
> It's just a dumb effing construct to begin with.<br>
><br>
> > ><br>
> > > The BlockingQueue is used in the following contexts:<br>
> > ><br>
> > > * Serving AssetRequests<br>
> > > - This should be solved with a specialized ThreadStart queue
that<br>
> > > news up threads whenever something tries to add to it or
if there's<br>
> > > something in the queue, up to a specified max of concurrent
requests.<br>
> > Isn't starting up threads an expensive process? Perhaps a ThreadPool<br>
> > instead if we wanted to go down that route?<br>
><br>
> Yes and No. Starting up threads is indeed 'expensive', but only in
<br>
> relation to how big the work item is. For example, when transferring
<br>
> an Asset, the cost of creating the thread is a fraction of the cost
of <br>
> actually transferring it.<br>
><br>
> It's exactly the over-excessive use of thread pools for long running
<br>
> work items that's exhausting the thread pool as it is right now.<br>
><br>
> Thread pools should be used only when you KNOW the work item is a
<br>
> (relatively) small one.<br>
><br>
> If we WANT thread re-use for this special case depicted above, we
can <br>
> simply track and reuse the threads as they are finished.<br>
afair, at the moment the thread processing the asset BlockingQueue <br>
doesn't send the packets directly, but rather chops them up and places
<br>
them on the on PacketQueue. I don't know if this is expensive or
not.<br>
<br>
--<br>
justincc<br>
_______________________________________________<br>
Opensim-dev mailing list<br>
Opensim-dev@lists.berlios.de<br>
https://lists.berlios.de/mailman/listinfo/opensim-dev<br>
</font><tt><font size=2>_______________________________________________<br>
Opensim-dev mailing list<br>
Opensim-dev@lists.berlios.de<br>
https://lists.berlios.de/mailman/listinfo/opensim-dev<br>
</font></tt>
<br>