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 CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
  require 'rake/gempackagetask'
5
5
  require 'tools/rakehelp'
6
6
 
7
- GEM_VERSION="0.6.1"
7
+ GEM_VERSION="0.6.2"
8
8
 
9
9
  setup_extension('fastthread', 'fastthread')
10
10
 
@@ -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 = rb_rescue2(rb_thread_wakeup, shift_list(list),
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
- if (mutex->waiting.entries) {
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
- rb_rescue2(rb_thread_run, waking, return_value, Qnil, private_eThreadError, 0);
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
- rb_rescue2(rb_thread_run, waking, return_value, Qnil, private_eThreadError, 0);
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(VALUE self, VALUE mutex_v)
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
- rb_rescue2(rb_thread_run, waking, return_value, Qnil, private_eThreadError, 0);
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 void
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
- swap_class("Mutex", rb_cMutex);
829
- swap_class("ConditionVariable", rb_cConditionVariable);
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
- rb_cConditionVariable = rb_class_new(rb_cObject);
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
- rb_cQueue = rb_class_new(rb_cObject);
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
- rb_cSizedQueue = rb_class_new(rb_cQueue);
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
- // swap classes atomically to avoid race conditions
900
- rb_thread_critical = 1;
901
- rb_ensure(swap_classes, Qnil, set_critical, 0);
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
 
@@ -0,0 +1,11 @@
1
+ require 'fastthread'
2
+ require 'thread'
3
+
4
+ mutex = Mutex.new
5
+ condition = ConditionVariable.new
6
+ t = Thread.new do
7
+ mutex.lock
8
+ condition.wait mutex
9
+ end
10
+ exit
11
+
data/test/test_condvar.rb CHANGED
@@ -14,7 +14,7 @@ class TestCondVar < Test::Unit::TestCase
14
14
  ready = false
15
15
 
16
16
  t = Thread.new do
17
- nil until m.synchronize { ready }
17
+ nil until ( Thread.pass ; m.synchronize { ready } )
18
18
  m.synchronize { s << "b" }
19
19
  cv.signal
20
20
  end
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.1
7
- date: 2006-12-31 00:00:00 -05:00
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