Re: Lock.lock("info")..
Nathan Reynolds via Concurrency-interest <[email protected]> Mon, 22 Nov 2021 13:06:37 -0700
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CALMUwcrGHVX8b7L_mG1svS6iL2cGHbQFJZpfi3gDaYu=oC-dDA@mail.gmail.com> |
--===============8761810746236268676== Content-Type: multipart/alternative; boundary="00000000000032bbc805d1662ab1" --00000000000032bbc805d1662ab1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Why not create a logger that holds some number of debug log messages in memory for each thread until a warning or error is logged? When a warning or error is logged, then the logger writes all the messages regardless of the log level. Hence, the code does debug logging calls and the logger takes care of the rest. In the case of locks, change to a try lock with a timeout. When the timeout happens, log an error. The logger does the rest. I find this to be very helpful since the debug log messages can be captured from ancestor and preceding sibling methods. This way I get much more contextual information than what can be captured right before attempting to acquire the lock. On Mon, Nov 22, 2021 at 9:23 AM Gregg Wonderly via Concurrency-interest < [email protected]> wrote: > For me, there is a whole list of =E2=80=9CReporting=E2=80=9D based interf= aces that I > typically use. These names are an example, but they help me separate > implementations out so that logging vs console and historical data repos > etc, can all be inserted into my =E2=80=9CReporting=E2=80=9D. > > public interface Report { > String getDetails(); > String getLocation(); > bool hasLocation(); > } > > public interface Reportable { > Report getReport(); > } > > public interface Reporter { > String getName(); > void report( Reportable obj ); > } > > public class ReportingManager { > static ReportingManager getDefault(); > static Iterator<Reporter> getAll(); > static Reporter getReporter( String which ); > static void add( Reporter reporter ); > static void remove( Reporter reporter ); > static void removeAll(); > static void report( Reportable rep ); > static void report( Report rep ); > static void reportTo( String rptr, Reportable rep ); > static void reportTo( String rptr, Report rep ); > } > > With these kinds of interfaces, logging and all kinds of details get > abstracted into something that is pluggable and extendable. Your lock > holder can be a Reportable for example, so that it can be any object your > need to report something about. This kind of API might be interesting to > the OpenJDK, but is just not something that is explicitly about concurren= cy > as Doug indicates. > > Gregg Wonderly > > On Nov 22, 2021, at 3:30 AM, Kedar C. Raybagkar via Concurrency-interest = < > [email protected]> wrote: > > Yes, that was the holder that I was referring to. > > I understand that Lock is not a repo but a small String that captures the > reason for acquiring the lock would have helped. I have it already > addressed; so just wanted to check if there is a possibility to have that > API so that we don't have to create similar holders that capture the reas= on > as the reasons are dynamic in nature. > > Do appreciate the follow ups! We can close this thread. > > Thanks & Regards, > -Kedar. > > On Mon, 22 Nov 2021 at 14:51, David Holmes <[email protected]> > wrote: > >> Hi Kedar, >> >> >> >> I added back the c-I list. >> >> >> >> So IIUC you want to store information about the last operation with the >> lock, so that next time if you can=E2=80=99t get it (?) because teardown= has not >> finished, you could query the lock to see what the previous operation wa= s, >> and report that back. In other words your lock is the only common object >> you have for different messages in the same session so you want to use i= t >> to channel the data through. In such a situation I would expect you to m= ap >> a session id to a Session object which includes the lock and any other d= ata >> about the session you might want to track. If that is the =E2=80=9CHolde= r=E2=80=9D that you >> previously referred to then that is the best way to do this IMO. >> >> >> >> It isn=E2=80=99t the job of a Lock to act as a data repository, so I wou= ld not >> consider adding the kind of API you have suggested. >> >> >> >> Cheers, >> >> David >> >> >> >> *From:* Kedar C. Raybagkar <[email protected]> >> *Sent:* Monday, 22 November 2021 6:18 PM >> *To:* [email protected] >> *Subject:* Re: [concurrency-interest] Lock.lock("info").. >> >> >> >> Consider a simple servlet. >> >> >> >> This servlet creates an AsyncFuture and waits for say 3 seconds max >> before sending the response out to the caller. If the response is genera= ted >> within 3 seconds it is sent out, else we send a long running response (w= ith >> reference to the future) to the caller. The caller if receives the respo= nse >> it displays it else if it finds a long running response then again calls >> the server by passing the reference id. >> >> >> >> Now we have this future execute the job in two distinct ways. #1 waits >> till the entire operation is complete and #2 with no wait for the tear d= own >> process. >> >> >> >> Teardown process serializes some data and it takes some time before it >> completes but the response is already generated and can be sent to the >> caller. >> >> >> >> In case of #2 what we do is on the queue we push the response early on >> and then continue to do teardown. The caller waits on the queue and as s= oon >> as the response is received it returns that to the caller. >> >> >> >> Usually the user takes time to send further requests to the server and i= n >> normal scenarios the tear down is finished by the time the next request >> comes. When the next request comes to the server we have to ensure that = the >> prior requests teardown is complete. So we have used Lock to latch on an= d >> release it once teardown is complete. The latch is acquired as per the >> session (UUID reference) so that when the next request comes it gets the >> same latch and waits on the latch to be released. >> >> >> >> As we need to keep all these Locks in a map based on the UUID (session >> identifier) we need to hold on to the encapsulated lock DTO that holds t= he >> purpose of what was being done before. >> >> >> >> Hope I am able to explain it to your satisfaction. >> >> >> >> Thanks & Regards, >> >> >> >> >> >> On Mon, 22 Nov 2021 at 12:01, David Holmes <[email protected]> >> wrote: >> >> Why do you need a Holder object for the lock and condition? The lock and >> condition belong in the object whose state they are guarding and >> interacting with. If you are using external synchronization you wont hav= e >> an encapsulated lock/condition but the code using the lock/condition has= to >> know what it is actually dealing with and so that code can report that >> information. >> >> >> >> David >> >> >> >> *From:* Kedar C. Raybagkar <[email protected]> >> *Sent:* Monday, 22 November 2021 4:23 PM >> *To:* [email protected] >> *Cc:* [email protected] >> *Subject:* Re: [concurrency-interest] Lock.lock("info").. >> >> >> >> Thank you, David. >> >> >> >> That is what I have been doing but instead of having to encapsulate into >> a separate holder object I thought it might be a good idea to have some = API >> directly available. As encapsulation also results in having a Value Obje= ct >> with hashcode and equals being overridden and then keeping them in a map >> with thread ids. This is already within the lock; just an additional str= ing >> or object parameter may help solve the problem. >> >> >> >> Regards, >> >> -Kedar. >> >> >> >> On Mon, 22 Nov 2021 at 11:28, David Holmes <[email protected]> >> wrote: >> >> Hi Kedar, >> >> >> >> The Lock and Condition should be encapsulated inside the object that >> needs them, and that object can provide whatever additional information = the >> callers needs on its own methods. >> >> >> >> Cheers, >> >> David >> >> >> >> *From:* Concurrency-interest <[email protected]= > >> *On Behalf Of *Kedar C. Raybagkar via Concurrency-interest >> *Sent:* Monday, 22 November 2021 3:43 PM >> *To:* [email protected] >> *Subject:* [concurrency-interest] Lock.lock("info").. >> >> >> >> Hi, >> >> >> >> Can we have something API where we can provide why we have acquired a >> lock so that when waiting on a condition if timed out we can fetch the i= nfo >> and return it to the caller? >> >> >> >> Regards, >> >> -Kedar. >> >> _______________________________________________ > Concurrency-interest mailing list > [email protected] > http://cs.oswego.edu/mailman/listinfo/concurrency-interest > > > _______________________________________________ > Concurrency-interest mailing list > [email protected] > http://cs.oswego.edu/mailman/listinfo/concurrency-interest > --00000000000032bbc805d1662ab1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>Why not create a logger that holds some number of deb= ug log messages in memory for each thread until a warning or error is logge= d?=C2=A0 When a warning or error is logged, then the logger writes all the = messages regardless of the log level.=C2=A0 Hence, the code does debug logg= ing calls and the logger takes care of the rest.</div><div><br></div><div> = In the case of locks, change to a try lock with a timeout.=C2=A0 When the t= imeout happens, log an error.=C2=A0 The logger does the rest.=C2=A0 I find = this to be very helpful since the debug log messages can be captured from a= ncestor and preceding sibling methods.=C2=A0 This way I get much more conte= xtual information than what can be captured right before attempting to acqu= ire the lock.</div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" cl= ass=3D"gmail_attr">On Mon, Nov 22, 2021 at 9:23 AM Gregg Wonderly via Concu= rrency-interest <<a href=3D"mailto:[email protected]">c= [email protected]</a>> wrote:<br></div><blockquote class= =3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg= b(204,204,204);padding-left:1ex"><div style=3D"overflow-wrap: break-word;">= For me, there is a whole list of =E2=80=9CReporting=E2=80=9D based interfac= es that I typically use.=C2=A0 These names are an example, but they help me= separate implementations out so that logging vs console and historical dat= a repos etc, can all be inserted into my =E2=80=9CReporting=E2=80=9D.<div><= br></div><div>public interface Report {</div><div><span style=3D"white-spac= e:pre-wrap"> </span>String getDetails();</div><div><span style=3D"white-spa= ce:pre-wrap"> </span>String getLocation();</div><div><span style=3D"white-s= pace:pre-wrap"> </span>bool hasLocation();</div><div>}<span style=3D"white-= space:pre-wrap"> </span></div><div><div><br></div><div>public interface Rep= ortable {</div><div><span style=3D"white-space:pre-wrap"> </span>Report get= Report();</div><div>}</div><div><br></div><div>public interface Reporter {<= /div><div><span style=3D"white-space:pre-wrap"> </span>String getName();</d= iv><div><span style=3D"white-space:pre-wrap"> </span>void report( Reportabl= e obj );</div><div>}</div><div><br></div><div>public class ReportingManager= {</div><div><span style=3D"white-space:pre-wrap"> </span>static ReportingM= anager getDefault();</div><div><span style=3D"white-space:pre-wrap"> </span= >static Iterator<Reporter> getAll();</div><div><span style=3D"white-s= pace:pre-wrap"> </span>static Reporter getReporter( String which );</div><d= iv><span style=3D"white-space:pre-wrap"> </span>static void add( Reporter r= eporter );</div><div><span style=3D"white-space:pre-wrap"> </span>static vo= id remove( Reporter reporter );</div><div><span style=3D"white-space:pre-wr= ap"> </span>static void removeAll();</div><div><span style=3D"white-space:p= re-wrap"> </span>static void report( Reportable rep );</div><div><span styl= e=3D"white-space:pre-wrap"> </span>static void report( Report rep );</div><= div><span style=3D"white-space:pre-wrap"> </span>static void reportTo( Stri= ng rptr, Reportable rep );</div><div><span style=3D"white-space:pre-wrap"> = </span>static void reportTo( String rptr, Report rep );</div><div>}<br><div= ><br></div><div>With these kinds of interfaces, logging and all kinds of de= tails get abstracted into something that is pluggable and extendable.=C2=A0= Your lock holder can be a Reportable for example, so that it can be any ob= ject your need to report something about.=C2=A0 This kind of API might be i= nteresting to the OpenJDK, but is just not something that is explicitly abo= ut concurrency as Doug indicates.</div><div><br></div><div>Gregg Wonderly</= div><div><br><blockquote type=3D"cite"><div>On Nov 22, 2021, at 3:30 AM, Ke= dar C. Raybagkar via Concurrency-interest <<a href=3D"mailto:concurrency= [email protected]" target=3D"_blank">[email protected]= du</a>> wrote:</div><br><div><div dir=3D"ltr">Yes, that was the holder t= hat I was referring to.<div><br><div>I understand that Lock is not a repo b= ut a small String that captures the reason for acquiring the lock would hav= e helped. I have it already addressed; so just wanted to check if there is = a possibility=C2=A0to have that API so that we don't have=C2=A0to creat= e similar holders that capture the reason as the reasons are dynamic in nat= ure.</div><div><br></div><div>Do appreciate the follow ups! We can close th= is thread.</div><div><br></div><div>Thanks &=C2=A0Regards,</div><div>-K= edar.</div></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" clas= s=3D"gmail_attr">On Mon, 22 Nov 2021 at 14:51, David Holmes <<a href=3D"= mailto:[email protected]" target=3D"_blank">[email protected]= </a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:= 0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">= <div lang=3D"EN-AU"><div><p class=3D"MsoNormal"><span>Hi Kedar,<u></u><u></= u></span></p><p class=3D"MsoNormal"><span><u></u>=C2=A0<u></u></span></p><p= class=3D"MsoNormal"><span>I added back the c-I list.<u></u><u></u></span><= /p><p class=3D"MsoNormal"><span><u></u>=C2=A0<u></u></span></p><p class=3D"= MsoNormal"><span>So IIUC you want to store information about the last opera= tion with the lock, so that next time if you can=E2=80=99t get it (?) becau= se teardown has not finished, you could query the lock to see what the prev= ious operation was, and report that back. In other words your lock is the o= nly common object you have for different messages in the same session so yo= u want to use it to channel the data through. In such a situation I would e= xpect you to map a session id to a Session object which includes the lock a= nd any other data about the session you might want to track. If that is the= =E2=80=9CHolder=E2=80=9D that you previously referred to then that is the = best way to do this IMO.<u></u><u></u></span></p><p class=3D"MsoNormal"><sp= an><u></u>=C2=A0<u></u></span></p><p class=3D"MsoNormal"><span>It isn=E2=80= =99t the job of a Lock to act as a data repository, so I would not consider= adding the kind of API you have suggested.<u></u><u></u></span></p><p clas= s=3D"MsoNormal"><span><u></u>=C2=A0<u></u></span></p><p class=3D"MsoNormal"= ><span>Cheers,<u></u><u></u></span></p><p class=3D"MsoNormal"><span>David<u= ></u><u></u></span></p><p class=3D"MsoNormal"><span><u></u>=C2=A0<u></u></s= pan></p><div style=3D"border-color:rgb(225,225,225) currentcolor currentcol= or;border-style:solid none none;border-width:1pt medium medium;padding:3pt = 0cm 0cm"><p class=3D"MsoNormal"><b><span lang=3D"EN-US">From:</span></b><sp= an lang=3D"EN-US"> Kedar C. Raybagkar <<a href=3D"mailto:kedar.raybagkar= @gmail.com" target=3D"_blank">[email protected]</a>> <br><b>Sent= :</b> Monday, 22 November 2021 6:18 PM<br><b>To:</b> <a href=3D"mailto:dhol= [email protected]" target=3D"_blank">[email protected]</a><br><b>Subject:</b> Re:= [concurrency-interest] Lock.lock("info")..<u></u><u></u></span><= /p></div><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p><div><p class=3D"Ms= oNormal">Consider a simple servlet.<u></u><u></u></p><div><p class=3D"MsoNo= rmal"><u></u>=C2=A0<u></u></p></div><div><p class=3D"MsoNormal">This servle= t creates an AsyncFuture and waits for say 3 seconds max before sending the= response out to the caller. If the response is generated within 3 seconds = it is sent out, else we send a long running response (with reference to the= future) to the caller. The caller if receives the response it displays it = else if it finds a long running response then again calls the server by pas= sing the reference id.<u></u><u></u></p></div><div><p class=3D"MsoNormal"><= u></u>=C2=A0<u></u></p></div><div><p class=3D"MsoNormal">Now we have this f= uture execute the job in two distinct ways. #1 waits till the entire operat= ion is complete and #2 with no wait for the tear down process.<u></u><u></u= ></p></div><div><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div><div><= p class=3D"MsoNormal">Teardown process serializes some data and it takes so= me=C2=A0time before it completes but the response is already generated and = can be sent to the caller.<u></u><u></u></p></div><div><p class=3D"MsoNorma= l"><u></u>=C2=A0<u></u></p></div><div><p class=3D"MsoNormal">In case of #2 = what we do is on the queue we push the response early on and then continue = to do teardown. The caller waits on the queue and as soon as the response= =C2=A0is received=C2=A0it returns that to the caller.<u></u><u></u></p></di= v><div><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div><div><p class= =3D"MsoNormal">Usually the user takes time to send further requests to the = server and in normal scenarios the tear down is finished by the time the ne= xt request comes. When the next request comes to the server we have to ensu= re that the prior requests teardown is complete. So we have used Lock to la= tch on and release it once teardown is complete. The latch is acquired as p= er the session (UUID reference) so that when the next request comes it gets= the same latch and waits on the latch to be released.<u></u><u></u></p></d= iv><div><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div><div><p class= =3D"MsoNormal">As we need to keep all these Locks in a map based on the UUI= D (session identifier) we need to hold on to the encapsulated lock DTO that= holds the purpose of what was being done before.<u></u><u></u></p></div><d= iv><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div><div><p class=3D"Ms= oNormal">Hope I am able to explain it to your satisfaction.<u></u><u></u></= p></div><div><p class=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div><div><p c= lass=3D"MsoNormal">Thanks & Regards,<u></u><u></u></p></div><div><p cla= ss=3D"MsoNormal"><u></u>=C2=A0<u></u></p></div></div><p class=3D"MsoNormal"= ><u></u>=C2=A0<u></u></p><div><div><p class=3D"MsoNormal">On Mon, 22 Nov 20= 21 at 12:01, David Holmes <<a href=3D"mailto:[email protected]" t= arget=3D"_blank">[email protected]</a>> wrote:<u></u><u></u></p><= /div><blockquote style=3D"border-color:currentcolor currentcolor currentcol= or rgb(204,204,204);border-style:none none none solid;border-width:medium m= edium medium 1pt;padding:0cm 0cm 0cm 6pt;margin-left:4.8pt;margin-right:0cm= "><div><div><p class=3D"MsoNormal">Why do you need a Holder object for the = lock and condition? The lock and condition belong in the object whose state= they are guarding and interacting with. If you are using external synchron= ization you wont have an encapsulated lock/condition but the code using the= lock/condition has to know what it is actually dealing with and so that co= de can report that information.<u></u><u></u></p><p class=3D"MsoNormal">=C2= =A0<u></u><u></u></p><p class=3D"MsoNormal">David<u></u><u></u></p><p class= =3D"MsoNormal">=C2=A0<u></u><u></u></p><div style=3D"border-color:rgb(225,2= 25,225) currentcolor currentcolor;border-style:solid none none;border-width= :1pt medium medium;padding:3pt 0cm 0cm"><p class=3D"MsoNormal"><b><span lan= g=3D"EN-US">From:</span></b><span lang=3D"EN-US"> Kedar C. Raybagkar <<a= href=3D"mailto:[email protected]" target=3D"_blank">kedar.raybagka= [email protected]</a>> <br><b>Sent:</b> Monday, 22 November 2021 4:23 PM<br><b= >To:</b> <a href=3D"mailto:[email protected]" target=3D"_blank">dholmes@ieee= .org</a><br><b>Cc:</b> <a href=3D"mailto:[email protected]= " target=3D"_blank">[email protected]</a><br><b>Subject:</= b> Re: [concurrency-interest] Lock.lock("info")..</span><u></u><u= ></u></p></div><p class=3D"MsoNormal">=C2=A0<u></u><u></u></p><div><div><p = class=3D"MsoNormal">Thank you, David.<u></u><u></u></p></div><div><p class= =3D"MsoNormal">=C2=A0<u></u><u></u></p></div><div><p class=3D"MsoNormal">Th= at is what I have been doing but instead of having to encapsulate=C2=A0into= a separate holder object I thought it might be a good idea to have some AP= I directly available. As encapsulation=C2=A0also results in having a Value = Object with hashcode and equals being overridden and then keeping them in a= map with thread ids. This is already within the lock; just an additional s= tring or object parameter may help solve the=C2=A0problem.<u></u><u></u></p= ></div><div><p class=3D"MsoNormal">=C2=A0<u></u><u></u></p></div><div><p cl= ass=3D"MsoNormal">Regards,<u></u><u></u></p></div><div><p class=3D"MsoNorma= l">-Kedar.<u></u><u></u></p></div></div><p class=3D"MsoNormal">=C2=A0<u></u= ><u></u></p><div><div><p class=3D"MsoNormal">On Mon, 22 Nov 2021 at 11:28, = David Holmes <<a href=3D"mailto:[email protected]" target=3D"_bla= nk">[email protected]</a>> wrote:<u></u><u></u></p></div><blockqu= ote style=3D"border-color:currentcolor currentcolor currentcolor rgb(204,20= 4,204);border-style:none none none solid;border-width:medium medium medium = 1pt;padding:0cm 0cm 0cm 6pt;margin:5pt 0cm 5pt 4.8pt"><div><div><p class=3D= "MsoNormal">Hi Kedar,<u></u><u></u></p><p class=3D"MsoNormal">=C2=A0<u></u>= <u></u></p><p class=3D"MsoNormal">The Lock and Condition should be encapsul= ated inside the object that needs them, and that object can provide whateve= r additional information the callers needs on its own methods.<u></u><u></u= ></p><p class=3D"MsoNormal">=C2=A0<u></u><u></u></p><p class=3D"MsoNormal">= Cheers,<u></u><u></u></p><p class=3D"MsoNormal">David<u></u><u></u></p><p c= lass=3D"MsoNormal">=C2=A0<u></u><u></u></p><div style=3D"border-color:rgb(2= 25,225,225) currentcolor currentcolor;border-style:solid none none;border-w= idth:1pt medium medium;padding:3pt 0cm 0cm"><p class=3D"MsoNormal"><b><span= lang=3D"EN-US">From:</span></b><span lang=3D"EN-US"> Concurrency-interest = <<a href=3D"mailto:[email protected]" target=3D= "_blank">[email protected]</a>> <b>On Behalf Of= </b>Kedar C. Raybagkar via Concurrency-interest<br><b>Sent:</b> Monday, 22= November 2021 3:43 PM<br><b>To:</b> <a href=3D"mailto:concurrency-interest= @cs.oswego.edu" target=3D"_blank">[email protected]</a><br= ><b>Subject:</b> [concurrency-interest] Lock.lock("info")..</span= ><u></u><u></u></p></div><p class=3D"MsoNormal">=C2=A0<u></u><u></u></p><di= v><p class=3D"MsoNormal">Hi,<u></u><u></u></p><div><p class=3D"MsoNormal">= =C2=A0<u></u><u></u></p></div><div><p class=3D"MsoNormal">Can we have somet= hing API where we can provide why we have acquired a lock so that when wait= ing on a condition if timed out=C2=A0we can fetch the info and return it to= the caller?<u></u><u></u></p></div><div><p class=3D"MsoNormal">=C2=A0<u></= u><u></u></p></div><div><p class=3D"MsoNormal">Regards,<u></u><u></u></p></= div><div><p class=3D"MsoNormal">-Kedar.<u></u><u></u></p></div></div></div>= </div></blockquote></div></div></div></blockquote></div></div></div></block= quote></div> _______________________________________________<br>Concurrency-interest mai= ling list<br><a href=3D"mailto:[email protected]" target= =3D"_blank">[email protected]</a><br><a href=3D"http://cs.= oswego.edu/mailman/listinfo/concurrency-interest" target=3D"_blank">http://= cs.oswego.edu/mailman/listinfo/concurrency-interest</a><br></div></blockquo= te></div><br></div></div></div>____________________________________________= ___<br> Concurrency-interest mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">Con= [email protected]</a><br> <a href=3D"http://cs.oswego.edu/mailman/listinfo/concurrency-interest" rel= =3D"noreferrer" target=3D"_blank">http://cs.oswego.edu/mailman/listinfo/con= currency-interest</a><br> </blockquote></div> --00000000000032bbc805d1662ab1-- --===============8761810746236268676== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Concurrency-interest mailing list [email protected] http://cs.oswego.edu/mailman/listinfo/concurrency-interest --===============8761810746236268676==--