fastthread 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|