blob: 83921637e6c186e9efa4cb798a5db5e983405336 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// Copyright (C) 2004-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17//
18// As a special exception, you may use this file as part of a free software
19// library without restriction. Specifically, if other files instantiate
20// templates or use macros or inline functions from this file, or you compile
21// this file and link it with other files to produce an executable, this
22// file does not by itself cause the resulting executable to be covered by
23// the GNU General Public License. This exception does not however
24// invalidate any other reasons why the executable file might be covered by
25// the GNU General Public License.
26//
27// This exception applies only to the code released under the name GNU
28// Common C++. If you copy code from other releases into a copy of GNU
29// Common C++, as the General Public License permits, the exception does
30// not apply to the code that you add in this way. To avoid misleading
31// anyone as to the status of such modified files, you must delete
32// this exception notice from them.
33//
34// If you write modifications of your own for GNU Common C++, it is your choice
35// whether to permit this exception to apply to your modifications.
36// If you do not wish that, delete this exception notice.
37//
38
39#include <cc++/config.h>
40#include <cc++/export.h>
41#include <cc++/thread.h>
42#include <cc++/misc.h>
43#include "private.h"
44
45#ifdef CCXX_NAMESPACES
46namespace ost {
47#endif
48
49Runlist::Runlist(unsigned count) :
50Mutex()
51{
52 first = last = NULL;
53 limit = count;
54 used = 0;
55}
56
57void Runlist::del(Runable *run)
58{
59 enter();
60 if(run->list != this) {
61 leave();
62 return;
63 }
64
65 if(!run->next && !run->prev) {
66 if(first == run && last == run)
67 first = last = NULL;
68 else
69 --used;
70 run->list = NULL;
71 leave();
72 check();
73 return;
74 }
75
76 if(run->next)
77 run->next->prev = run->prev;
78 else
79 last = run->prev;
80
81 if(run->prev)
82 run->prev->next = run->next;
83 else
84 first = run->next;
85
86 run->list = NULL;
87 run->next = run->prev = NULL;
88 leave();
89 check();
90 return;
91}
92
93void Runlist::set(unsigned count)
94{
95 limit = count;
96 check();
97}
98
99bool Runlist::add(Runable *run)
100{
101 if(run->list)
102 run->list->del(run);
103
104 run->list = this;
105
106 enter();
107 if(used < limit) {
108 ++used;
109 leave();
110 return true;
111 }
112 run->next = NULL;
113 if(last) {
114 run->prev = last;
115 last = run;
116 }
117 else {
118 run->prev = NULL;
119 first = last = run;
120 }
121 leave();
122 return false;
123}
124
125void Runlist::check(void)
126{
127 Runable *run;
128
129 for(;;) {
130 enter();
131 if(used >= limit || !first) {
132 leave();
133 return;
134 }
135 run = first;
136 first = run->next;
137 if(first)
138 first->prev = NULL;
139 else
140 last = NULL;
141 run->next = run->prev = NULL;
142 if(run->list == this)
143 ++used;
144 else
145 run = NULL;
146 leave();
147 if(run)
148 run->ready();
149 }
150}
151
152Runable::Runable()
153{
154 list = NULL;
155 next = prev = NULL;
156}
157
158bool Runable::starting(Runlist *list)
159{
160 stoping();
161 return list->add(this);
162}
163
164void Runable::stoping(void)
165{
166 if(list)
167 list->del(this);
168}
169
170Runable::~Runable()
171{
172 stoping();
173}
174
175#ifdef CCXX_NAMESPACES
176}
177#endif
178
179/** EMACS **
180 * Local variables:
181 * mode: c++
182 * c-basic-offset: 4
183 * End:
184 */