pike.git/
src/
threads.c
Branch:
Tag:
Non-build tags
All tags
No tags
2006-01-29
2006-01-29 16:41:18 by Henrik Grubbström (Grubba) <grubba@grubba.org>
8349b4f2d5c62ca5477cb2184903848c399b196e (
68
lines) (+
54
/-
14
)
[
Show
|
Annotate
]
Branch:
7.9
Potential fix for the cond problem that mast noted.
Rev: src/threads.c:1.247
2:
|| This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
-
|| $Id: threads.c,v 1.
246
2006/01/
28
05
:
17
:
11
mast
Exp $
+
|| $Id: threads.c,v 1.
247
2006/01/
29
16
:
41
:
18
grubba
Exp $
*/ #ifndef CONFIGURE_TEST
1480:
/*! @endclass */
-
#define THIS_COND ((COND_T *)(CURRENT_STORAGE))
-
+
/*! @class Condition *! *! Implementation of condition variables.
1498:
*! @[Mutex] */
+
struct pike_cond {
+
COND_T cond;
+
int wait_count;
+
};
+
+
#define THIS_COND ((pike_cond *)(CURRENT_STORAGE))
+
/*! @decl void wait(Thread.MutexKey mutex_key) *! *! Wait for condition.
1519:
*! versions since it unavoidably leads to programs with races *! and/or deadlocks. *!
+
*! @note
+
*! Note also that any threads waiting on the condition will be
+
*! waken up when it gets destructed.
+
*!
*! @seealso *! @[Mutex->lock()] */
1526:
{ struct object *key, *mutex_obj; struct mutex_storage *mut;
-
COND
_
T
*c;
+
struct pike
_
cond
*c;
if(threads_disabled) Pike_error("Cannot wait for conditions when threads are disabled!\n");
1555:
/* Wait and allow mutex operations */ SWAP_OUT_CURRENT_THREAD();
-
co_wait_interpreter(c);
+
c->wait_count++;
+
co_wait_interpreter(
&(
c
->cond
)
)
;
+
c->wait_count--;
SWAP_IN_CURRENT_THREAD(); /* Lock mutex */
1594:
*! @seealso *! @[broadcast()] */
-
void f_cond_signal(INT32 args)
{ pop_n_elems(args); co_signal(THIS_COND);
}
+
void f_cond_signal(INT32 args)
+
{
+
pop_n_elems(args);
+
co_signal(
&(
THIS_COND
->cond
)
)
;
+
}
/*! @decl void broadcast() *!
1603:
*! @seealso *! @[signal()] */
-
void f_cond_broadcast(INT32 args)
{ pop_n_elems(args); co_broadcast(THIS_COND);
}
+
void f_cond_broadcast(INT32 args)
+
{
+
pop_n_elems(args);
+
co_broadcast(
&(
THIS_COND
->cond
)
)
;
+
}
-
void init_cond_obj(struct object *o)
{ co_init(THIS_COND); }
+
void init_cond_obj(struct object *o)
+
{
+
co_init(
&(
THIS_COND
->cond
)
)
;
+
THIS_COND->wait_count = 0;
+
}
void exit_cond_obj(struct object *o) {
-
/*
FIXME:
This
fails
(at
least
with
pthread)
if
we're
destructed
-
*
explicitly
and
there
are
threads
waiting
on
this
cond
.
We
should
-
*
probably
do
a
broadcast
here
instead
and
only
destroy
the
cond
-
* when
actually
running
out
of
refs
. */
-
co_
destroy
(THIS_COND);
+
/*
Wake
up
any
threads
that
might
be
waiting
on
this cond.
+
*
+
*
Note that we
are
already
destructed
(o->prog
==
NULL),
+
* so wait_count can't increase
.
+
*
+
*
FIXME:
This
code
wouldn't
be
needed
if
exit
callbacks
were
called
+
*
only
when
the
ref
count
reaches
zero
.
+
*
/
grubba 2006-01-29
+
*/
+
while (THIS_COND->wait_count) {
+
co_
broadcast
(THIS_COND);
+
+
THREADS_ALLOW();
+
#ifdef HAVE_NO_YIELD
+
sleep(0);
+
#else /* HAVE_NO_YIELD */
+
th_yield();
+
#endif /* HAVE_NO_YIELD */
+
THREADS_DISALLOW();
}
-
+
co_destroy(&(THIS_COND->cond));
+
}
/*! @endclass */
2204:
end_class("mutex_compat_7_4", 0); START_NEW_PROGRAM_ID(THREAD_CONDITION);
-
ADD_STORAGE(
COND
_
T
);
+
ADD_STORAGE(
struct pike
_
cond
);
ADD_FUNCTION("wait",f_cond_wait, tFunc(tObjIs_THREAD_MUTEX_KEY,tVoid),0); ADD_FUNCTION("signal",f_cond_signal,tFunc(tNone,tVoid),0);