fastthread 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/ext/fastthread/fastthread.c +180 -48
- data/ext/fastthread/foo.rb +11 -0
- data/test/test_condvar.rb +1 -1
- data/test/test_queue.rb +27 -0
- metadata +3 -2
    
        data/Rakefile
    CHANGED
    
    
    
        data/ext/fastthread/fastthread.c
    CHANGED
    
    | @@ -17,8 +17,6 @@ static VALUE avoid_mem_pools; | |
| 17 17 | 
             
            #define USE_MEM_POOLS !RTEST(avoid_mem_pools)
         | 
| 18 18 | 
             
            #endif
         | 
| 19 19 |  | 
| 20 | 
            -
            static ID mutex_ivar;
         | 
| 21 | 
            -
             | 
| 22 20 | 
             
            static VALUE rb_cMutex;
         | 
| 23 21 | 
             
            static VALUE rb_cConditionVariable;
         | 
| 24 22 | 
             
            /* post-1.8.5 Ruby exposes rb_eThreadError; earlier versions do not */
         | 
| @@ -45,6 +43,8 @@ typedef struct _List { | |
| 45 43 | 
             
              unsigned long size;
         | 
| 46 44 | 
             
            } List;
         | 
| 47 45 |  | 
| 46 | 
            +
            static void init_list _((List *));
         | 
| 47 | 
            +
             | 
| 48 48 | 
             
            static void
         | 
| 49 49 | 
             
            init_list(list)
         | 
| 50 50 | 
             
              List *list;
         | 
| @@ -55,6 +55,8 @@ init_list(list) | |
| 55 55 | 
             
              list->size = 0;
         | 
| 56 56 | 
             
            }
         | 
| 57 57 |  | 
| 58 | 
            +
            static void mark_list _((List *));
         | 
| 59 | 
            +
             | 
| 58 60 | 
             
            static void
         | 
| 59 61 | 
             
            mark_list(list)
         | 
| 60 62 | 
             
              List *list;
         | 
| @@ -65,6 +67,8 @@ mark_list(list) | |
| 65 67 | 
             
              }
         | 
| 66 68 | 
             
            }
         | 
| 67 69 |  | 
| 70 | 
            +
            static void free_entries _((Entry *));
         | 
| 71 | 
            +
             | 
| 68 72 | 
             
            static void
         | 
| 69 73 | 
             
            free_entries(first)
         | 
| 70 74 | 
             
              Entry *first;
         | 
| @@ -77,6 +81,8 @@ free_entries(first) | |
| 77 81 | 
             
              }
         | 
| 78 82 | 
             
            }
         | 
| 79 83 |  | 
| 84 | 
            +
            static void finalize_list _((List *));
         | 
| 85 | 
            +
             | 
| 80 86 | 
             
            static void
         | 
| 81 87 | 
             
            finalize_list(list)
         | 
| 82 88 | 
             
              List *list;
         | 
| @@ -85,6 +91,8 @@ finalize_list(list) | |
| 85 91 | 
             
              free_entries(list->entry_pool);
         | 
| 86 92 | 
             
            }
         | 
| 87 93 |  | 
| 94 | 
            +
            static void push_list _((List *, VALUE));
         | 
| 95 | 
            +
             | 
| 88 96 | 
             
            static void
         | 
| 89 97 | 
             
            push_list(list, value)
         | 
| 90 98 | 
             
              List *list;
         | 
| @@ -112,6 +120,8 @@ push_list(list, value) | |
| 112 120 | 
             
              ++list->size;
         | 
| 113 121 | 
             
            }
         | 
| 114 122 |  | 
| 123 | 
            +
            static void push_multiple_list _((List *, VALUE *, unsigned));
         | 
| 124 | 
            +
             | 
| 115 125 | 
             
            static void
         | 
| 116 126 | 
             
            push_multiple_list(list, values, count)
         | 
| 117 127 | 
             
              List *list;
         | 
| @@ -124,6 +134,8 @@ push_multiple_list(list, values, count) | |
| 124 134 | 
             
              }
         | 
| 125 135 | 
             
            }
         | 
| 126 136 |  | 
| 137 | 
            +
            static VALUE shift_list _((List *));
         | 
| 138 | 
            +
             | 
| 127 139 | 
             
            static VALUE
         | 
| 128 140 | 
             
            shift_list(list)
         | 
| 129 141 | 
             
              List *list;
         | 
| @@ -152,6 +164,8 @@ shift_list(list) | |
| 152 164 | 
             
              return value;
         | 
| 153 165 | 
             
            }
         | 
| 154 166 |  | 
| 167 | 
            +
            static void clear_list _((List *));
         | 
| 168 | 
            +
             | 
| 155 169 | 
             
            static void
         | 
| 156 170 | 
             
            clear_list(list)
         | 
| 157 171 | 
             
              List *list;
         | 
| @@ -169,6 +183,8 @@ clear_list(list) | |
| 169 183 | 
             
              }
         | 
| 170 184 | 
             
            }
         | 
| 171 185 |  | 
| 186 | 
            +
            static VALUE array_from_list _((List const *));
         | 
| 187 | 
            +
             | 
| 172 188 | 
             
            static VALUE
         | 
| 173 189 | 
             
            array_from_list(list)
         | 
| 174 190 | 
             
              List const *list;
         | 
| @@ -182,6 +198,28 @@ array_from_list(list) | |
| 182 198 | 
             
              return ary;
         | 
| 183 199 | 
             
            }
         | 
| 184 200 |  | 
| 201 | 
            +
            static VALUE wake_thread _((VALUE));
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            static VALUE
         | 
| 204 | 
            +
            wake_thread(thread)
         | 
| 205 | 
            +
              VALUE thread;
         | 
| 206 | 
            +
            {
         | 
| 207 | 
            +
              return rb_rescue2(rb_thread_wakeup, thread,
         | 
| 208 | 
            +
                                return_value, Qnil, private_eThreadError, 0);
         | 
| 209 | 
            +
            }
         | 
| 210 | 
            +
             | 
| 211 | 
            +
            static VALUE run_thread _((VALUE));
         | 
| 212 | 
            +
             | 
| 213 | 
            +
            static VALUE
         | 
| 214 | 
            +
            run_thread(thread)
         | 
| 215 | 
            +
              VALUE thread;
         | 
| 216 | 
            +
            {
         | 
| 217 | 
            +
              return rb_rescue2(rb_thread_run, thread,
         | 
| 218 | 
            +
                                return_value, Qnil, private_eThreadError, 0);
         | 
| 219 | 
            +
            }
         | 
| 220 | 
            +
             | 
| 221 | 
            +
            static VALUE wake_one _((List *));
         | 
| 222 | 
            +
             | 
| 185 223 | 
             
            static VALUE
         | 
| 186 224 | 
             
            wake_one(list)
         | 
| 187 225 | 
             
              List *list;
         | 
| @@ -190,13 +228,14 @@ wake_one(list) | |
| 190 228 |  | 
| 191 229 | 
             
              waking = Qnil;
         | 
| 192 230 | 
             
              while ( list->entries && !RTEST(waking) ) {
         | 
| 193 | 
            -
                waking =  | 
| 194 | 
            -
                                    return_value, Qnil, private_eThreadError, 0);
         | 
| 231 | 
            +
                waking = wake_thread(shift_list(list));
         | 
| 195 232 | 
             
              }
         | 
| 196 233 |  | 
| 197 234 | 
             
              return waking;
         | 
| 198 235 | 
             
            }
         | 
| 199 236 |  | 
| 237 | 
            +
            static VALUE wake_all _((List *));
         | 
| 238 | 
            +
             | 
| 200 239 | 
             
            static VALUE
         | 
| 201 240 | 
             
            wake_all(list)
         | 
| 202 241 | 
             
              List *list;
         | 
| @@ -207,11 +246,29 @@ wake_all(list) | |
| 207 246 | 
             
              return Qnil;
         | 
| 208 247 | 
             
            }
         | 
| 209 248 |  | 
| 249 | 
            +
            static void assert_no_survivors _((List *, const char *, void *));
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            static void
         | 
| 252 | 
            +
            assert_no_survivors(waiting, label, addr)
         | 
| 253 | 
            +
              List *waiting;
         | 
| 254 | 
            +
              const char *label;
         | 
| 255 | 
            +
              void *addr;
         | 
| 256 | 
            +
            {
         | 
| 257 | 
            +
              Entry *entry;
         | 
| 258 | 
            +
              for ( entry = waiting->entries ; entry ; entry = entry->next ) {
         | 
| 259 | 
            +
                if (RTEST(wake_thread(entry->value))) {
         | 
| 260 | 
            +
                  rb_bug("%s %p freed with live thread(s) waiting", label, addr);
         | 
| 261 | 
            +
                }
         | 
| 262 | 
            +
              }
         | 
| 263 | 
            +
            }
         | 
| 264 | 
            +
             | 
| 210 265 | 
             
            typedef struct _Mutex {
         | 
| 211 266 | 
             
              VALUE owner;
         | 
| 212 267 | 
             
              List waiting;
         | 
| 213 268 | 
             
            } Mutex;
         | 
| 214 269 |  | 
| 270 | 
            +
            static void mark_mutex _((Mutex *));
         | 
| 271 | 
            +
             | 
| 215 272 | 
             
            static void
         | 
| 216 273 | 
             
            mark_mutex(mutex)
         | 
| 217 274 | 
             
              Mutex *mutex;
         | 
| @@ -220,6 +277,8 @@ mark_mutex(mutex) | |
| 220 277 | 
             
              mark_list(&mutex->waiting);
         | 
| 221 278 | 
             
            }
         | 
| 222 279 |  | 
| 280 | 
            +
            static void finalize_mutex _((Mutex *));
         | 
| 281 | 
            +
             | 
| 223 282 | 
             
            static void
         | 
| 224 283 | 
             
            finalize_mutex(mutex)
         | 
| 225 284 | 
             
              Mutex *mutex;
         | 
| @@ -227,17 +286,19 @@ finalize_mutex(mutex) | |
| 227 286 | 
             
              finalize_list(&mutex->waiting);
         | 
| 228 287 | 
             
            }
         | 
| 229 288 |  | 
| 289 | 
            +
            static void free_mutex _((Mutex *));
         | 
| 290 | 
            +
             | 
| 230 291 | 
             
            static void
         | 
| 231 292 | 
             
            free_mutex(mutex)
         | 
| 232 293 | 
             
              Mutex *mutex;
         | 
| 233 294 | 
             
            {
         | 
| 234 | 
            -
               | 
| 235 | 
            -
                rb_bug("mutex %p freed with thread(s) waiting", mutex);
         | 
| 236 | 
            -
              }
         | 
| 295 | 
            +
              assert_no_survivors(&mutex->waiting, "mutex", mutex);
         | 
| 237 296 | 
             
              finalize_mutex(mutex);
         | 
| 238 297 | 
             
              free(mutex);
         | 
| 239 298 | 
             
            }
         | 
| 240 299 |  | 
| 300 | 
            +
            static void init_mutex _((Mutex *));
         | 
| 301 | 
            +
             | 
| 241 302 | 
             
            static void
         | 
| 242 303 | 
             
            init_mutex(mutex)
         | 
| 243 304 | 
             
              Mutex *mutex;
         | 
| @@ -258,6 +319,8 @@ rb_mutex_alloc(klass) | |
| 258 319 | 
             
              return Data_Wrap_Struct(klass, mark_mutex, free_mutex, mutex);
         | 
| 259 320 | 
             
            }
         | 
| 260 321 |  | 
| 322 | 
            +
            static VALUE rb_mutex_locked_p _((VALUE));
         | 
| 323 | 
            +
             | 
| 261 324 | 
             
            static VALUE
         | 
| 262 325 | 
             
            rb_mutex_locked_p(self)
         | 
| 263 326 | 
             
              VALUE self;
         | 
| @@ -267,6 +330,8 @@ rb_mutex_locked_p(self) | |
| 267 330 | 
             
              return ( RTEST(mutex->owner) ? Qtrue : Qfalse );
         | 
| 268 331 | 
             
            }
         | 
| 269 332 |  | 
| 333 | 
            +
            static VALUE rb_mutex_try_lock _((VALUE));
         | 
| 334 | 
            +
             | 
| 270 335 | 
             
            static VALUE
         | 
| 271 336 | 
             
            rb_mutex_try_lock(self)
         | 
| 272 337 | 
             
              VALUE self;
         | 
| @@ -288,6 +353,8 @@ rb_mutex_try_lock(self) | |
| 288 353 | 
             
              return result;
         | 
| 289 354 | 
             
            }
         | 
| 290 355 |  | 
| 356 | 
            +
            static void lock_mutex _((Mutex *));
         | 
| 357 | 
            +
             | 
| 291 358 | 
             
            static void
         | 
| 292 359 | 
             
            lock_mutex(mutex)
         | 
| 293 360 | 
             
              Mutex *mutex;
         | 
| @@ -308,6 +375,8 @@ lock_mutex(mutex) | |
| 308 375 | 
             
              rb_thread_critical = 0;
         | 
| 309 376 | 
             
            }
         | 
| 310 377 |  | 
| 378 | 
            +
            static VALUE rb_mutex_lock _((VALUE));
         | 
| 379 | 
            +
             | 
| 311 380 | 
             
            static VALUE
         | 
| 312 381 | 
             
            rb_mutex_lock(self)
         | 
| 313 382 | 
             
              VALUE self;
         | 
| @@ -318,6 +387,8 @@ rb_mutex_lock(self) | |
| 318 387 | 
             
              return self;
         | 
| 319 388 | 
             
            }
         | 
| 320 389 |  | 
| 390 | 
            +
            static VALUE unlock_mutex_inner _((Mutex *));
         | 
| 391 | 
            +
             | 
| 321 392 | 
             
            static VALUE
         | 
| 322 393 | 
             
            unlock_mutex_inner(mutex)
         | 
| 323 394 | 
             
              Mutex *mutex;
         | 
| @@ -333,6 +404,8 @@ unlock_mutex_inner(mutex) | |
| 333 404 | 
             
              return waking;
         | 
| 334 405 | 
             
            }
         | 
| 335 406 |  | 
| 407 | 
            +
            static VALUE set_critical _((VALUE));
         | 
| 408 | 
            +
             | 
| 336 409 | 
             
            static VALUE
         | 
| 337 410 | 
             
            set_critical(value)
         | 
| 338 411 | 
             
              VALUE value;
         | 
| @@ -341,6 +414,8 @@ set_critical(value) | |
| 341 414 | 
             
              return Qnil;
         | 
| 342 415 | 
             
            }
         | 
| 343 416 |  | 
| 417 | 
            +
            static VALUE unlock_mutex _((Mutex *));
         | 
| 418 | 
            +
             | 
| 344 419 | 
             
            static VALUE
         | 
| 345 420 | 
             
            unlock_mutex(mutex)
         | 
| 346 421 | 
             
              Mutex *mutex;
         | 
| @@ -355,12 +430,14 @@ unlock_mutex(mutex) | |
| 355 430 | 
             
              }
         | 
| 356 431 |  | 
| 357 432 | 
             
              if (RTEST(waking)) {
         | 
| 358 | 
            -
                 | 
| 433 | 
            +
                run_thread(waking);
         | 
| 359 434 | 
             
              }
         | 
| 360 435 |  | 
| 361 436 | 
             
              return Qtrue;
         | 
| 362 437 | 
             
            }
         | 
| 363 438 |  | 
| 439 | 
            +
            static VALUE rb_mutex_unlock _((VALUE));
         | 
| 440 | 
            +
             | 
| 364 441 | 
             
            static VALUE
         | 
| 365 442 | 
             
            rb_mutex_unlock(self)
         | 
| 366 443 | 
             
              VALUE self;
         | 
| @@ -375,6 +452,8 @@ rb_mutex_unlock(self) | |
| 375 452 | 
             
              }
         | 
| 376 453 | 
             
            }
         | 
| 377 454 |  | 
| 455 | 
            +
            static VALUE rb_mutex_exclusive_unlock_inner _((Mutex *));
         | 
| 456 | 
            +
             | 
| 378 457 | 
             
            static VALUE
         | 
| 379 458 | 
             
            rb_mutex_exclusive_unlock_inner(mutex)
         | 
| 380 459 | 
             
              Mutex *mutex;
         | 
| @@ -385,6 +464,8 @@ rb_mutex_exclusive_unlock_inner(mutex) | |
| 385 464 | 
             
              return waking;
         | 
| 386 465 | 
             
            }
         | 
| 387 466 |  | 
| 467 | 
            +
            static VALUE rb_mutex_exclusive_unlock _((VALUE));
         | 
| 468 | 
            +
             | 
| 388 469 | 
             
            static VALUE
         | 
| 389 470 | 
             
            rb_mutex_exclusive_unlock(self)
         | 
| 390 471 | 
             
              VALUE self;
         | 
| @@ -401,12 +482,14 @@ rb_mutex_exclusive_unlock(self) | |
| 401 482 | 
             
              }
         | 
| 402 483 |  | 
| 403 484 | 
             
              if (RTEST(waking)) {
         | 
| 404 | 
            -
                 | 
| 485 | 
            +
                run_thread(waking);
         | 
| 405 486 | 
             
              }
         | 
| 406 487 |  | 
| 407 488 | 
             
              return self;
         | 
| 408 489 | 
             
            }
         | 
| 409 490 |  | 
| 491 | 
            +
            static VALUE rb_mutex_synchronize _((VALUE));
         | 
| 492 | 
            +
             | 
| 410 493 | 
             
            static VALUE
         | 
| 411 494 | 
             
            rb_mutex_synchronize(self)
         | 
| 412 495 | 
             
              VALUE self;
         | 
| @@ -419,6 +502,8 @@ typedef struct _ConditionVariable { | |
| 419 502 | 
             
              List waiting;
         | 
| 420 503 | 
             
            } ConditionVariable;
         | 
| 421 504 |  | 
| 505 | 
            +
            static void mark_condvar _((ConditionVariable *));
         | 
| 506 | 
            +
             | 
| 422 507 | 
             
            static void
         | 
| 423 508 | 
             
            mark_condvar(condvar)
         | 
| 424 509 | 
             
              ConditionVariable *condvar;
         | 
| @@ -426,6 +511,8 @@ mark_condvar(condvar) | |
| 426 511 | 
             
              mark_list(&condvar->waiting);
         | 
| 427 512 | 
             
            }
         | 
| 428 513 |  | 
| 514 | 
            +
            static void finalize_condvar _((ConditionVariable *));
         | 
| 515 | 
            +
             | 
| 429 516 | 
             
            static void
         | 
| 430 517 | 
             
            finalize_condvar(condvar)
         | 
| 431 518 | 
             
              ConditionVariable *condvar;
         | 
| @@ -433,14 +520,19 @@ finalize_condvar(condvar) | |
| 433 520 | 
             
              finalize_list(&condvar->waiting);
         | 
| 434 521 | 
             
            }
         | 
| 435 522 |  | 
| 523 | 
            +
            static void free_condvar _((ConditionVariable *));
         | 
| 524 | 
            +
             | 
| 436 525 | 
             
            static void
         | 
| 437 526 | 
             
            free_condvar(condvar)
         | 
| 438 527 | 
             
              ConditionVariable *condvar;
         | 
| 439 528 | 
             
            {
         | 
| 529 | 
            +
              assert_no_survivors(&condvar->waiting, "condition variable", condvar);
         | 
| 440 530 | 
             
              finalize_condvar(condvar);
         | 
| 441 531 | 
             
              free(condvar);
         | 
| 442 532 | 
             
            }
         | 
| 443 533 |  | 
| 534 | 
            +
            static void init_condvar _((ConditionVariable *));
         | 
| 535 | 
            +
             | 
| 444 536 | 
             
            static void
         | 
| 445 537 | 
             
            init_condvar(condvar)
         | 
| 446 538 | 
             
              ConditionVariable *condvar;
         | 
| @@ -462,6 +554,8 @@ rb_condvar_alloc(klass) | |
| 462 554 | 
             
              return Data_Wrap_Struct(klass, mark_condvar, free_condvar, condvar);
         | 
| 463 555 | 
             
            }
         | 
| 464 556 |  | 
| 557 | 
            +
            static void wait_condvar _((ConditionVariable *, Mutex *));
         | 
| 558 | 
            +
             | 
| 465 559 | 
             
            static void
         | 
| 466 560 | 
             
            wait_condvar(condvar, mutex)
         | 
| 467 561 | 
             
              ConditionVariable *condvar;
         | 
| @@ -483,8 +577,12 @@ wait_condvar(condvar, mutex) | |
| 483 577 | 
             
              lock_mutex(mutex);
         | 
| 484 578 | 
             
            }
         | 
| 485 579 |  | 
| 580 | 
            +
            static VALUE rb_condvar_wait _((VALUE, VALUE));
         | 
| 581 | 
            +
             | 
| 486 582 | 
             
            static VALUE
         | 
| 487 | 
            -
            rb_condvar_wait( | 
| 583 | 
            +
            rb_condvar_wait(self, mutex_v)
         | 
| 584 | 
            +
              VALUE self;
         | 
| 585 | 
            +
              VALUE mutex_v;
         | 
| 488 586 | 
             
            {
         | 
| 489 587 | 
             
              ConditionVariable *condvar;
         | 
| 490 588 | 
             
              Mutex *mutex;
         | 
| @@ -500,6 +598,8 @@ rb_condvar_wait(VALUE self, VALUE mutex_v) | |
| 500 598 | 
             
              return self;
         | 
| 501 599 | 
             
            }
         | 
| 502 600 |  | 
| 601 | 
            +
            static VALUE rb_condvar_broadcast _((VALUE));
         | 
| 602 | 
            +
             | 
| 503 603 | 
             
            static VALUE
         | 
| 504 604 | 
             
            rb_condvar_broadcast(self)
         | 
| 505 605 | 
             
              VALUE self;
         | 
| @@ -515,6 +615,8 @@ rb_condvar_broadcast(self) | |
| 515 615 | 
             
              return self;
         | 
| 516 616 | 
             
            }
         | 
| 517 617 |  | 
| 618 | 
            +
            static void signal_condvar _((ConditionVariable *condvar));
         | 
| 619 | 
            +
             | 
| 518 620 | 
             
            static void
         | 
| 519 621 | 
             
            signal_condvar(condvar)
         | 
| 520 622 | 
             
              ConditionVariable *condvar;
         | 
| @@ -523,10 +625,12 @@ signal_condvar(condvar) | |
| 523 625 | 
             
              rb_thread_critical = 1;
         | 
| 524 626 | 
             
              waking = rb_ensure(wake_one, (VALUE)&condvar->waiting, set_critical, 0);
         | 
| 525 627 | 
             
              if (RTEST(waking)) {
         | 
| 526 | 
            -
                 | 
| 628 | 
            +
                run_thread(waking);
         | 
| 527 629 | 
             
              }
         | 
| 528 630 | 
             
            }
         | 
| 529 631 |  | 
| 632 | 
            +
            static VALUE rb_condvar_signal _((VALUE));
         | 
| 633 | 
            +
             | 
| 530 634 | 
             
            static VALUE
         | 
| 531 635 | 
             
            rb_condvar_signal(self)
         | 
| 532 636 | 
             
              VALUE self;
         | 
| @@ -545,6 +649,8 @@ typedef struct _Queue { | |
| 545 649 | 
             
              unsigned long capacity;
         | 
| 546 650 | 
             
            } Queue;
         | 
| 547 651 |  | 
| 652 | 
            +
            static void mark_queue _((Queue *));
         | 
| 653 | 
            +
             | 
| 548 654 | 
             
            static void
         | 
| 549 655 | 
             
            mark_queue(queue)
         | 
| 550 656 | 
             
              Queue *queue;
         | 
| @@ -555,6 +661,8 @@ mark_queue(queue) | |
| 555 661 | 
             
              mark_list(&queue->values);
         | 
| 556 662 | 
             
            }
         | 
| 557 663 |  | 
| 664 | 
            +
            static void finalize_queue _((Queue *));
         | 
| 665 | 
            +
             | 
| 558 666 | 
             
            static void
         | 
| 559 667 | 
             
            finalize_queue(queue)
         | 
| 560 668 | 
             
              Queue *queue;
         | 
| @@ -565,14 +673,21 @@ finalize_queue(queue) | |
| 565 673 | 
             
              finalize_list(&queue->values);
         | 
| 566 674 | 
             
            }
         | 
| 567 675 |  | 
| 676 | 
            +
            static void free_queue _((Queue *));
         | 
| 677 | 
            +
             | 
| 568 678 | 
             
            static void
         | 
| 569 679 | 
             
            free_queue(queue)
         | 
| 570 680 | 
             
              Queue *queue;
         | 
| 571 681 | 
             
            {
         | 
| 682 | 
            +
              assert_no_survivors(&queue->mutex.waiting, "queue", queue);
         | 
| 683 | 
            +
              assert_no_survivors(&queue->space_available.waiting, "queue", queue);
         | 
| 684 | 
            +
              assert_no_survivors(&queue->value_available.waiting, "queue", queue);
         | 
| 572 685 | 
             
              finalize_queue(queue);
         | 
| 573 686 | 
             
              free(queue);
         | 
| 574 687 | 
             
            }
         | 
| 575 688 |  | 
| 689 | 
            +
            static void init_queue _((Queue *));
         | 
| 690 | 
            +
             | 
| 576 691 | 
             
            static void
         | 
| 577 692 | 
             
            init_queue(queue)
         | 
| 578 693 | 
             
              Queue *queue;
         | 
| @@ -596,6 +711,8 @@ rb_queue_alloc(klass) | |
| 596 711 | 
             
              return Data_Wrap_Struct(klass, mark_queue, free_queue, queue);
         | 
| 597 712 | 
             
            }
         | 
| 598 713 |  | 
| 714 | 
            +
            static VALUE rb_queue_marshal_load _((VALUE, VALUE));
         | 
| 715 | 
            +
             | 
| 599 716 | 
             
            static VALUE
         | 
| 600 717 | 
             
            rb_queue_marshal_load(self, data)
         | 
| 601 718 | 
             
              VALUE self;
         | 
| @@ -618,6 +735,8 @@ rb_queue_marshal_load(self, data) | |
| 618 735 | 
             
              return self;
         | 
| 619 736 | 
             
            }
         | 
| 620 737 |  | 
| 738 | 
            +
            static VALUE rb_queue_marshal_dump _((VALUE));
         | 
| 739 | 
            +
             | 
| 621 740 | 
             
            static VALUE
         | 
| 622 741 | 
             
            rb_queue_marshal_dump(self)
         | 
| 623 742 | 
             
              VALUE self;
         | 
| @@ -631,6 +750,8 @@ rb_queue_marshal_dump(self) | |
| 631 750 | 
             
              return rb_marshal_dump(array, Qnil);
         | 
| 632 751 | 
             
            }
         | 
| 633 752 |  | 
| 753 | 
            +
            static VALUE rb_queue_clear _((VALUE));
         | 
| 754 | 
            +
             | 
| 634 755 | 
             
            static VALUE
         | 
| 635 756 | 
             
            rb_queue_clear(self)
         | 
| 636 757 | 
             
              VALUE self;
         | 
| @@ -646,6 +767,8 @@ rb_queue_clear(self) | |
| 646 767 | 
             
              return self;
         | 
| 647 768 | 
             
            }
         | 
| 648 769 |  | 
| 770 | 
            +
            static VALUE rb_queue_empty_p _((VALUE));
         | 
| 771 | 
            +
             | 
| 649 772 | 
             
            static VALUE
         | 
| 650 773 | 
             
            rb_queue_empty_p(self)
         | 
| 651 774 | 
             
              VALUE self;
         | 
| @@ -661,6 +784,8 @@ rb_queue_empty_p(self) | |
| 661 784 | 
             
              return result;
         | 
| 662 785 | 
             
            }
         | 
| 663 786 |  | 
| 787 | 
            +
            static VALUE rb_queue_length _((VALUE));
         | 
| 788 | 
            +
             | 
| 664 789 | 
             
            static VALUE
         | 
| 665 790 | 
             
            rb_queue_length(self)
         | 
| 666 791 | 
             
              VALUE self;
         | 
| @@ -676,6 +801,8 @@ rb_queue_length(self) | |
| 676 801 | 
             
              return result;
         | 
| 677 802 | 
             
            }
         | 
| 678 803 |  | 
| 804 | 
            +
            static VALUE rb_queue_num_waiting _((VALUE));
         | 
| 805 | 
            +
             | 
| 679 806 | 
             
            static VALUE
         | 
| 680 807 | 
             
            rb_queue_num_waiting(self)
         | 
| 681 808 | 
             
              VALUE self;
         | 
| @@ -692,6 +819,8 @@ rb_queue_num_waiting(self) | |
| 692 819 | 
             
              return result;
         | 
| 693 820 | 
             
            }
         | 
| 694 821 |  | 
| 822 | 
            +
            static VALUE rb_queue_pop _((int, VALUE *, VALUE));
         | 
| 823 | 
            +
             | 
| 695 824 | 
             
            static VALUE
         | 
| 696 825 | 
             
            rb_queue_pop(argc, argv, self)
         | 
| 697 826 | 
             
              int argc;
         | 
| @@ -730,6 +859,8 @@ rb_queue_pop(argc, argv, self) | |
| 730 859 | 
             
              return result;
         | 
| 731 860 | 
             
            }
         | 
| 732 861 |  | 
| 862 | 
            +
            static VALUE rb_queue_push _((VALUE, VALUE));
         | 
| 863 | 
            +
             | 
| 733 864 | 
             
            static VALUE
         | 
| 734 865 | 
             
            rb_queue_push(self, value)
         | 
| 735 866 | 
             
              VALUE self;
         | 
| @@ -749,6 +880,8 @@ rb_queue_push(self, value) | |
| 749 880 | 
             
              return self;
         | 
| 750 881 | 
             
            }
         | 
| 751 882 |  | 
| 883 | 
            +
            static VALUE rb_sized_queue_max _((VALUE));
         | 
| 884 | 
            +
             | 
| 752 885 | 
             
            static VALUE
         | 
| 753 886 | 
             
            rb_sized_queue_max(self)
         | 
| 754 887 | 
             
              VALUE self;
         | 
| @@ -764,6 +897,8 @@ rb_sized_queue_max(self) | |
| 764 897 | 
             
              return result;
         | 
| 765 898 | 
             
            }
         | 
| 766 899 |  | 
| 900 | 
            +
            static VALUE rb_sized_queue_max_set _((VALUE, VALUE));
         | 
| 901 | 
            +
             | 
| 767 902 | 
             
            static VALUE
         | 
| 768 903 | 
             
            rb_sized_queue_max_set(self, value)
         | 
| 769 904 | 
             
              VALUE self;
         | 
| @@ -797,6 +932,8 @@ rb_sized_queue_max_set(self, value) | |
| 797 932 |  | 
| 798 933 | 
             
            /* Existing code expects to be able to serialize Mutexes... */
         | 
| 799 934 |  | 
| 935 | 
            +
            static VALUE dummy_load _((VALUE, VALUE)); 
         | 
| 936 | 
            +
             | 
| 800 937 | 
             
            static VALUE
         | 
| 801 938 | 
             
            dummy_load(self, string)
         | 
| 802 939 | 
             
              VALUE self;
         | 
| @@ -805,6 +942,8 @@ dummy_load(self, string) | |
| 805 942 | 
             
              return Qnil;
         | 
| 806 943 | 
             
            }
         | 
| 807 944 |  | 
| 945 | 
            +
            static VALUE dummy_dump _((VALUE));
         | 
| 946 | 
            +
             | 
| 808 947 | 
             
            static VALUE
         | 
| 809 948 | 
             
            dummy_dump(self)
         | 
| 810 949 | 
             
              VALUE self;
         | 
| @@ -812,40 +951,13 @@ dummy_dump(self) | |
| 812 951 | 
             
              return rb_str_new2("");
         | 
| 813 952 | 
             
            }
         | 
| 814 953 |  | 
| 815 | 
            -
            static  | 
| 816 | 
            -
            swap_class(name, value)
         | 
| 817 | 
            -
              const char *name;
         | 
| 818 | 
            -
              VALUE value;
         | 
| 819 | 
            -
            {
         | 
| 820 | 
            -
              rb_mod_remove_const(rb_cObject, rb_str_new2(name));
         | 
| 821 | 
            -
              rb_const_set(rb_cObject, rb_intern(name), value);
         | 
| 822 | 
            -
            }
         | 
| 954 | 
            +
            static VALUE setup_classes _((VALUE));
         | 
| 823 955 |  | 
| 824 | 
            -
            static VALUE
         | 
| 825 | 
            -
            swap_classes(unused)
         | 
| 956 | 
            +
            static VALUE setup_classes(unused)
         | 
| 826 957 | 
             
              VALUE unused;
         | 
| 827 958 | 
             
            {
         | 
| 828 | 
            -
               | 
| 829 | 
            -
               | 
| 830 | 
            -
              swap_class("Queue", rb_cQueue);
         | 
| 831 | 
            -
              swap_class("SizedQueue", rb_cSizedQueue);
         | 
| 832 | 
            -
              return Qnil;
         | 
| 833 | 
            -
            }
         | 
| 834 | 
            -
             | 
| 835 | 
            -
            void
         | 
| 836 | 
            -
            Init_fastthread()
         | 
| 837 | 
            -
            {
         | 
| 838 | 
            -
              avoid_mem_pools = rb_gv_get("$fastthread_avoid_mem_pools");
         | 
| 839 | 
            -
              rb_global_variable(&avoid_mem_pools);
         | 
| 840 | 
            -
              rb_define_variable("$fastthread_avoid_mem_pools", &avoid_mem_pools);
         | 
| 841 | 
            -
             | 
| 842 | 
            -
              mutex_ivar = rb_intern("__mutex__");
         | 
| 843 | 
            -
             | 
| 844 | 
            -
              rb_require("thread");
         | 
| 845 | 
            -
             | 
| 846 | 
            -
              private_eThreadError = rb_const_get(rb_cObject, rb_intern("ThreadError"));
         | 
| 847 | 
            -
             | 
| 848 | 
            -
              rb_cMutex = rb_class_new(rb_cObject);
         | 
| 959 | 
            +
              rb_mod_remove_const(rb_cObject, ID2SYM(rb_intern("Mutex")));
         | 
| 960 | 
            +
              rb_cMutex = rb_define_class("Mutex", rb_cObject);
         | 
| 849 961 | 
             
              rb_define_alloc_func(rb_cMutex, rb_mutex_alloc);
         | 
| 850 962 | 
             
              rb_define_method(rb_cMutex, "marshal_load", dummy_load, 1);
         | 
| 851 963 | 
             
              rb_define_method(rb_cMutex, "marshal_dump", dummy_dump, 0);
         | 
| @@ -857,7 +969,8 @@ Init_fastthread() | |
| 857 969 | 
             
              rb_define_method(rb_cMutex, "exclusive_unlock", rb_mutex_exclusive_unlock, 0);
         | 
| 858 970 | 
             
              rb_define_method(rb_cMutex, "synchronize", rb_mutex_synchronize, 0);
         | 
| 859 971 |  | 
| 860 | 
            -
               | 
| 972 | 
            +
              rb_mod_remove_const(rb_cObject, ID2SYM(rb_intern("ConditionVariable")));
         | 
| 973 | 
            +
              rb_cConditionVariable = rb_define_class("ConditionVariable", rb_cObject);
         | 
| 861 974 | 
             
              rb_define_alloc_func(rb_cConditionVariable, rb_condvar_alloc);
         | 
| 862 975 | 
             
              rb_define_method(rb_cConditionVariable, "marshal_load", dummy_load, 1);
         | 
| 863 976 | 
             
              rb_define_method(rb_cConditionVariable, "marshal_dump", dummy_dump, 0);
         | 
| @@ -866,7 +979,8 @@ Init_fastthread() | |
| 866 979 | 
             
              rb_define_method(rb_cConditionVariable, "broadcast", rb_condvar_broadcast, 0);
         | 
| 867 980 | 
             
              rb_define_method(rb_cConditionVariable, "signal", rb_condvar_signal, 0);
         | 
| 868 981 |  | 
| 869 | 
            -
               | 
| 982 | 
            +
              rb_mod_remove_const(rb_cObject, ID2SYM(rb_intern("Queue")));
         | 
| 983 | 
            +
              rb_cQueue = rb_define_class("Queue", rb_cObject);
         | 
| 870 984 | 
             
              rb_define_alloc_func(rb_cQueue, rb_queue_alloc);
         | 
| 871 985 | 
             
              rb_define_method(rb_cQueue, "marshal_load", rb_queue_marshal_load, 1);
         | 
| 872 986 | 
             
              rb_define_method(rb_cQueue, "marshal_dump", rb_queue_marshal_dump, 0);
         | 
| @@ -882,7 +996,8 @@ Init_fastthread() | |
| 882 996 | 
             
              rb_alias(rb_cQueue, rb_intern("shift"), rb_intern("pop"));
         | 
| 883 997 | 
             
              rb_alias(rb_cQueue, rb_intern("size"), rb_intern("length"));
         | 
| 884 998 |  | 
| 885 | 
            -
               | 
| 999 | 
            +
              rb_mod_remove_const(rb_cObject, ID2SYM(rb_intern("SizedQueue")));
         | 
| 1000 | 
            +
              rb_cSizedQueue = rb_define_class("SizedQueue", rb_cQueue);
         | 
| 886 1001 | 
             
              rb_define_method(rb_cSizedQueue, "initialize", rb_sized_queue_max_set, 1);
         | 
| 887 1002 | 
             
              rb_define_method(rb_cSizedQueue, "clear", rb_queue_clear, 0);
         | 
| 888 1003 | 
             
              rb_define_method(rb_cSizedQueue, "empty?", rb_queue_empty_p, 0);
         | 
| @@ -896,8 +1011,25 @@ Init_fastthread() | |
| 896 1011 | 
             
              rb_alias(rb_cSizedQueue, rb_intern("deq"), rb_intern("pop"));
         | 
| 897 1012 | 
             
              rb_alias(rb_cSizedQueue, rb_intern("shift"), rb_intern("pop"));
         | 
| 898 1013 |  | 
| 899 | 
            -
               | 
| 900 | 
            -
             | 
| 901 | 
            -
             | 
| 1014 | 
            +
              return Qnil;
         | 
| 1015 | 
            +
            }
         | 
| 1016 | 
            +
             | 
| 1017 | 
            +
            void
         | 
| 1018 | 
            +
            Init_fastthread()
         | 
| 1019 | 
            +
            {
         | 
| 1020 | 
            +
              int saved_critical;
         | 
| 1021 | 
            +
             | 
| 1022 | 
            +
              avoid_mem_pools = rb_gv_get("$fastthread_avoid_mem_pools");
         | 
| 1023 | 
            +
              rb_global_variable(&avoid_mem_pools);
         | 
| 1024 | 
            +
              rb_define_variable("$fastthread_avoid_mem_pools", &avoid_mem_pools);
         | 
| 1025 | 
            +
             | 
| 1026 | 
            +
              rb_require("thread");
         | 
| 1027 | 
            +
             | 
| 1028 | 
            +
              private_eThreadError = rb_const_get(rb_cObject, rb_intern("ThreadError"));
         | 
| 1029 | 
            +
             | 
| 1030 | 
            +
              /* ensure that classes get replaced atomically */
         | 
| 1031 | 
            +
              saved_critical = rb_thread_critical;
         | 
| 1032 | 
            +
              rb_thread_critical = 1;
         | 
| 1033 | 
            +
              rb_ensure(setup_classes, Qnil, set_critical, (VALUE)saved_critical);
         | 
| 902 1034 | 
             
            }
         | 
| 903 1035 |  | 
    
        data/test/test_condvar.rb
    CHANGED
    
    
    
        data/test/test_queue.rb
    CHANGED
    
    | @@ -49,5 +49,32 @@ class TestQueue < Test::Unit::TestCase | |
| 49 49 | 
             
              def test_sized_queue_one
         | 
| 50 50 | 
             
                check_sequence( SizedQueue.new( 1 ) )
         | 
| 51 51 | 
             
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def check_serialization( k, *args )
         | 
| 54 | 
            +
                q1 = k.new *args
         | 
| 55 | 
            +
                %w(a b c d e f).each { |c| q1.push c }
         | 
| 56 | 
            +
                q2 = Marshal.load(Marshal.dump(q1))
         | 
| 57 | 
            +
                assert( ( q1.size == q2.size ), "queues are same size" )
         | 
| 58 | 
            +
                q1.size.times do
         | 
| 59 | 
            +
                  assert( ( q1.pop == q2.pop ), "same data" )
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
                [ q1, q2 ]
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              def test_queue_serialization
         | 
| 65 | 
            +
                check_serialization Queue
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              def test_sized_queue_serialization
         | 
| 69 | 
            +
                (q1, q2) = check_serialization SizedQueue, 20
         | 
| 70 | 
            +
                assert( ( q1.max == q2.max ), "maximum sizes equal" )
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def test_sized_queue_size
         | 
| 74 | 
            +
                q = SizedQueue.new 3
         | 
| 75 | 
            +
                assert_equal 3, q.max, "queue has expected max (3)"
         | 
| 76 | 
            +
                q.max = 5
         | 
| 77 | 
            +
                assert_equal 5, q.max, "queue has expected max (5)"
         | 
| 78 | 
            +
              end
         | 
| 52 79 | 
             
            end 
         | 
| 53 80 |  | 
    
        metadata
    CHANGED
    
    | @@ -3,8 +3,8 @@ rubygems_version: 0.8.11 | |
| 3 3 | 
             
            specification_version: 1
         | 
| 4 4 | 
             
            name: fastthread
         | 
| 5 5 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 6 | 
            -
              version: 0.6. | 
| 7 | 
            -
            date:  | 
| 6 | 
            +
              version: 0.6.2
         | 
| 7 | 
            +
            date: 2007-01-18 00:00:00 -05:00
         | 
| 8 8 | 
             
            summary: Optimized replacement for thread.rb primitives
         | 
| 9 9 | 
             
            require_paths: 
         | 
| 10 10 | 
             
            - lib
         | 
| @@ -36,6 +36,7 @@ files: | |
| 36 36 | 
             
            - test/test_queue.rb
         | 
| 37 37 | 
             
            - ext/fastthread/fastthread.c
         | 
| 38 38 | 
             
            - ext/fastthread/extconf.rb
         | 
| 39 | 
            +
            - ext/fastthread/foo.rb
         | 
| 39 40 | 
             
            - tools/rakehelp.rb
         | 
| 40 41 | 
             
            test_files: 
         | 
| 41 42 | 
             
            - test/test_all.rb
         |