G'day everyone, I've been staring at the cbdata semantics and use in the Squid-2 codebase (which translates pretty well to how its used in the Squid-3 codebase) and I'd like to get peoples' opinions on some stuff.
Generally, Squid's event driven methodology involves registering callbacks and using cbdata pointers, then relying on pointer validation/invalidation to determine whether to run a callback or not. This means that an owner or anyone else can simply call cbdataFree() (which, thankfully, shouldn't happen all that often in the codebase!) and it invalidates the callbacks which are registered for this. This makes using it in threaded code difficult. Take two threads, A and B. Consider A as "squid" and B as "work queue". A pushes some work into a work queue which is serviced by B, with the understanding that B will complete the work and then schedule a completion callback in A. A passes in a cbdata pointer for the work to be done. In both single-threade and multi-threaded code, a call to cbdataValid() holds true from the point its called to the point where another cbdata operation occurs on the code. For single threaded code this will generally be until the current threads program flow hits another cbdata operation - so you can assume that calling a callback immediately after checking cbdataValid() will hold correctly. But with two threads, A may schedule a callback which runs on B; A may then somewhere call cbdataFree() as part of some error/termination condition. A call to cbdataValid() in B only checks the pointer validity at call-time and, with the current code, will probably be invalid w/out locking or atomic instructions. Because of this, there's no guarantee that a cbdata pointer passed into another thread will ever really be usable, given the current coding methodology. Comments? Adrian
