On 04.10.2006, at 15:52, Stephen Deasey wrote:
Hmm... I think this does work. Here's how I read it:
First time arround, there will be 3 lookups. The next round should be simple deref. Allright this might compute. If you have this in a proc body the "themutex" will be a literal objects and will/should last "longer". I did it under the debugger in the nscp session and every time I get another object as "themutex". This is most probably because the code does not compile into bytecodes... OK. I can accept that. Still, you put this into frequently called procedure and there you go (literals are freed AFAIK, when procedure scope is exited): again you have global locking.
If one however does: set m themutex set t thecond ns_mutex lock $m while {} { ns_cond wait $c $m } ns_mutex unlock $m it WILL work. But how are you going to convey this information to the Tcl programmer??? He's implicitly serializing his app at the place he does not expect (lookup of the internal hash table).Actually, the above might NOT work... :-)
The first two init lines I havent counted for. It is just the remaining and in fact most specifically the ns_cond wait that was the problem as it may awake and sleep again.
But I'm having a hard time coming up with real world scenarios where that might happen...
This is OK. In the compiled code, things start to look somehow different.
But also when you use the "themutex" to put it in the nsv array you loose the caching effect of the object. Unlike with handles where you get the "real thing" immediately and need not global lock. Keeping the handles "away" from the user, means you need to manage handles yourself because the underlying C code needs handles/pointers. Every time you do that, you need to lock. In this case the global lock. So, nothing is for free. By allowing the tcl programmer some freedom, you charge him with some performance/concurrency. The best illustration: lexxsrv:nscp 7> ns_mutex unlock themutex Connection closed by foreign host. Here no check is done: you get a core. But if the themutex was locked before, all would be fine. In the Tcl threading extension I check mutex for a locked state and TCL_ERROR if lock was attempted on an already locked mutex OR an attempt was made to unlock never-locked mutex. This requires lots of low-level plumbing BUT it gives the Tcl coder maximum comfort. Neither way is "right" or "wrong". So you can't generally "avoid" using handles as this will lead you to situation where you must sacrify some speed/concurrency for getting the comfortable API.
