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
|