File: RubyQueue.cs

package info (click to toggle)
dlr-languages 20090805%2Bgit.e6b28d27%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 51,484 kB
  • ctags: 59,257
  • sloc: cs: 298,829; ruby: 159,643; xml: 19,872; python: 2,820; yacc: 1,960; makefile: 96; sh: 65
file content (115 lines) | stat: -rw-r--r-- 3,467 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using IronRuby.Runtime;
using IronRuby.Builtins;

namespace IronRuby.StandardLibrary.Threading {
    // Synchronized queue.
    [RubyClass("Queue")]
    public class RubyQueue {
        protected readonly Queue<object>/*!*/ _queue;
        protected int _waiting;

        public RubyQueue() {
            _queue = new Queue<object>();
        }

        protected RubyQueue(int capacity) {
            _queue = new Queue<object>(capacity);
        }

        private void Enqueue(object value) {
            lock (_queue) {
                _queue.Enqueue(value);
                Monitor.PulseAll(_queue);
            }
        }

        protected object Dequeue() {
            object value;
            lock (_queue) {
                _waiting++;

                try {
                    while (_queue.Count == 0) {
                        Monitor.Wait(_queue);
                    }
                } finally {
                    _waiting--;
                }
                value = _queue.Dequeue();
                Monitor.PulseAll(_queue);
            }
            return value;
        }
        
        [RubyMethod("enq")]
        [RubyMethod("push")]
        [RubyMethod("<<")]
        public static RubyQueue/*!*/ Enqueue(RubyQueue/*!*/ self, object value) {
            self.Enqueue(value);
            return self;
        }

        [RubyMethod("deq")]
        [RubyMethod("pop")]
        [RubyMethod("shift")]
        public static object Dequeue(RubyQueue/*!*/ self, [Optional]bool nonBlocking) {
            if (nonBlocking) {
                lock (self._queue) {
                    if (self._queue.Count == 0) {
                        throw new ThreadError("queue empty");
                    }
                    return self._queue.Dequeue();
                }
            }
            return self.Dequeue();
        }

        [RubyMethod("size")]
        [RubyMethod("length")]
        public static int GetCount(RubyQueue/*!*/ self) {
            lock (self._queue) {
                return self._queue.Count;
            }
        }

        [RubyMethod("clear")]
        public static RubyQueue/*!*/ Clear(RubyQueue/*!*/ self) {
            lock (self._queue) {
                self._queue.Clear();
            }
            return self;
        }

        [RubyMethod("empty?")]
        public static bool IsEmpty(RubyQueue/*!*/ self) {
            return GetCount(self) == 0;
        }

        [RubyMethod("num_waiting")]
        public static int GetNumberOfWaitingThreads(RubyQueue/*!*/ self) {
            return self._waiting;
        }
        
        // TODO:
        // "marshal_load" 
        // "marshal_dump" 
    }
}