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 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