| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -177,7 +177,7 @@ PyMUTEX_UNLOCK(PyMUTEX_T *cs) | |||
| 177 | 177 | typedef struct _PyCOND_T | |
| 178 | 178 | { | |
| 179 | 179 | HANDLE sem; | |
| 180 | - int waiting; | ||
| 180 | + int waiting; /* to allow PyCOND_SIGNAL to be a no-op */ | ||
| 181 | 181 | } PyCOND_T; | |
| 182 | 182 | ||
| 183 | 183 | Py_LOCAL_INLINE(int) | |
@@ -222,6 +222,10 @@ _PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) | |||
| 222 | 222 | * PyCOND_SIGNAL also decrements this value | |
| 223 | 223 | * and signals releases the mutex. This is benign because it | |
| 224 | 224 | * just means an extra spurious wakeup for a waiting thread. | |
| 225 | + * ('waiting' corresponds to the semaphore's "negative" count and | ||
| 226 | + * we may end up with e.g. (waiting == -1 && sem.count == 1). When | ||
| 227 | + * a new thread comes along, it will pass right throuhgh, having | ||
| 228 | + * adjusted it to (waiting == 0 && sem.count == 0). | ||
| 225 | 229 | */ | |
| 226 | 230 | ||
| 227 | 231 | if (wait == WAIT_FAILED) | |
@@ -246,10 +250,14 @@ PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us) | |||
| 246 | 250 | Py_LOCAL_INLINE(int) | |
| 247 | 251 | PyCOND_SIGNAL(PyCOND_T *cv) | |
| 248 | 252 | { | |
| 249 | - if (cv->waiting) { | ||
| 253 | + /* this test allows PyCOND_SIGNAL to be a no-op unless required | ||
| 254 | + * to wake someone up, thus preventing an unbounded increase of | ||
| 255 | + * the semaphore's internal counter. | ||
| 256 | + */ | ||
| 257 | + if (cv->waiting > 0) { | ||
| 250 | 258 | /* notifying thread decreases the cv->waiting count so that | |
| 251 | - * a delay between notify and wakeup doesn't cause a number | ||
| 252 | - * of extra ReleaseSemaphore calls | ||
| 259 | + * a delay between notify and actual wakeup of the target thread | ||
| 260 | + * doesn't cause a number of extra ReleaseSemaphore calls. | ||
| 253 | 261 | */ | |
| 254 | 262 | cv->waiting--; | |
| 255 | 263 | return ReleaseSemaphore(cv->sem, 1, NULL) ? 0 : -1; | |
@@ -260,7 +268,7 @@ PyCOND_SIGNAL(PyCOND_T *cv) | |||
| 260 | 268 | Py_LOCAL_INLINE(int) | |
| 261 | 269 | PyCOND_BROADCAST(PyCOND_T *cv) | |
| 262 | 270 | { | |
| 263 | - if (cv->waiting) { | ||
| 271 | + if (cv->waiting > 0) { | ||
| 264 | 272 | return ReleaseSemaphore(cv->sem, cv->waiting, NULL) ? 0 : -1; | |
| 265 | 273 | cv->waiting = 0; | |
| 266 | 274 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments