rbb 01/09/01 00:29:07
Modified: threadproc/win32 thread.c
Log:
Avoid a rather nasty bug in the Windows apr_thread_once function. We
basically, check the value before we increment, and after. By checking
before, we take a hit of one if statement, but avoid a kernel call in
most cases.
Submitted by: Will Rowe <[EMAIL PROTECTED]>
Revision Changes Path
1.38 +11 -0 apr/threadproc/win32/thread.c
Index: thread.c
===================================================================
RCS file: /home/cvs/apr/threadproc/win32/thread.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- thread.c 2001/09/01 07:10:25 1.37
+++ thread.c 2001/09/01 07:29:07 1.38
@@ -231,6 +231,17 @@
APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
void (*func)(void))
{
+ /* Quick escape hatch, and bug fix. The InterlockedIncrement
+ * call is just incrementing a long int, so it has the potential
+ * to wrap. Very unlikely, but still, that would be an almost
+ * impossible bug to hunt. With this, we might see one or two
+ * calls to InterlockedIncrement, but never enough to wrap the
+ * long int. This also saves us a kernel call for most calls to
+ * this function.
+ */
+ if (control->value) {
+ return APR_SUCCESS;
+ }
InterlockedIncrement(&control->value);
if (control->value == 1) {
func();