posix-threads.cc (_Jv_CondWait): Check errno' against EINTR, not
r'.
1999-09-07 Tom Tromey <tromey@cygnus.com> * posix-threads.cc (_Jv_CondWait): Check `errno' against EINTR, not `r'. Changed `done_sleeping' to a `bool'. 1999-09-07 Matt Welsh <mdw@cs.berkeley.edu * libjava/posix-threads.cc: Added _Jv_ThreadDataKey. Added FLAG_INTERRUPTED to indicate that a thread was interrupted by another thread, rather than by the GC. (_Jv_CondWait): Prevent premature thread wakeup by GC. (_Jv_InitThreads): Initialize _Jv_ThreadDataKey. * libjava/include/posix-threads.h (_Jv_ThreadCurrentData): New function. From-SVN: r29177
This commit is contained in:
parent
d07d525a85
commit
fd59e3a04e
3 changed files with 77 additions and 9 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
1999-09-07 Tom Tromey <tromey@cygnus.com>
|
||||||
|
|
||||||
|
* posix-threads.cc (_Jv_CondWait): Check `errno' against EINTR,
|
||||||
|
not `r'. Changed `done_sleeping' to a `bool'.
|
||||||
|
|
||||||
|
1999-09-07 Matt Welsh <mdw@cs.berkeley.edu
|
||||||
|
|
||||||
|
* libjava/posix-threads.cc: Added _Jv_ThreadDataKey.
|
||||||
|
Added FLAG_INTERRUPTED to indicate that a thread was interrupted
|
||||||
|
by another thread, rather than by the GC.
|
||||||
|
(_Jv_CondWait): Prevent premature thread wakeup by GC.
|
||||||
|
(_Jv_InitThreads): Initialize _Jv_ThreadDataKey.
|
||||||
|
* libjava/include/posix-threads.h (_Jv_ThreadCurrentData): New
|
||||||
|
function.
|
||||||
|
|
||||||
1999-09-03 Tom Tromey <tromey@cygnus.com>
|
1999-09-03 Tom Tromey <tromey@cygnus.com>
|
||||||
|
|
||||||
* configure: Rebuilt.
|
* configure: Rebuilt.
|
||||||
|
|
|
@ -249,6 +249,13 @@ _Jv_ThreadCurrent (void)
|
||||||
return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
|
return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline _Jv_Thread_t *
|
||||||
|
_Jv_ThreadCurrentData (void)
|
||||||
|
{
|
||||||
|
extern pthread_key_t _Jv_ThreadDataKey;
|
||||||
|
return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
|
||||||
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
_Jv_ThreadYield (void)
|
_Jv_ThreadYield (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,6 +46,10 @@ struct starter
|
||||||
// threads, so it is ok to make it a global here.
|
// threads, so it is ok to make it a global here.
|
||||||
pthread_key_t _Jv_ThreadKey;
|
pthread_key_t _Jv_ThreadKey;
|
||||||
|
|
||||||
|
// This is the key used to map from the POSIX thread value back to the
|
||||||
|
// _Jv_Thread_t* representing the thread.
|
||||||
|
pthread_key_t _Jv_ThreadDataKey;
|
||||||
|
|
||||||
// We keep a count of all non-daemon threads which are running. When
|
// We keep a count of all non-daemon threads which are running. When
|
||||||
// this reaches zero, _Jv_ThreadWait returns.
|
// this reaches zero, _Jv_ThreadWait returns.
|
||||||
static pthread_mutex_t daemon_mutex;
|
static pthread_mutex_t daemon_mutex;
|
||||||
|
@ -68,6 +72,8 @@ static int non_daemon_count;
|
||||||
#define FLAG_START 0x01
|
#define FLAG_START 0x01
|
||||||
// Thread is daemon.
|
// Thread is daemon.
|
||||||
#define FLAG_DAEMON 0x02
|
#define FLAG_DAEMON 0x02
|
||||||
|
// Thread was interrupted by _Jv_ThreadInterrupt.
|
||||||
|
#define FLAG_INTERRUPTED 0x04
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,20 +86,57 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
pthread_mutex_t *pmu = _Jv_PthreadGetMutex (mu);
|
pthread_mutex_t *pmu = _Jv_PthreadGetMutex (mu);
|
||||||
|
struct timespec ts;
|
||||||
|
jlong m, m2, startTime;
|
||||||
|
bool done_sleeping = false;
|
||||||
|
|
||||||
if (millis == 0 && nanos == 0)
|
if (millis == 0 && nanos == 0)
|
||||||
r = pthread_cond_wait (cv, pmu);
|
r = pthread_cond_wait (cv, pmu);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
startTime = java::lang::System::currentTimeMillis();
|
||||||
jlong m = millis + java::lang::System::currentTimeMillis ();
|
m = millis + startTime;
|
||||||
ts.tv_sec = m / 1000;
|
|
||||||
ts.tv_nsec = ((m % 1000) * 1000000) + nanos;
|
do
|
||||||
|
{
|
||||||
r = pthread_cond_timedwait (cv, pmu, &ts);
|
ts.tv_sec = m / 1000;
|
||||||
/* A timeout is a normal result. */
|
ts.tv_nsec = ((m % 1000) * 1000000) + nanos;
|
||||||
if (r && errno == ETIMEDOUT)
|
|
||||||
r = 0;
|
r = pthread_cond_timedwait (cv, pmu, &ts);
|
||||||
|
|
||||||
|
if (r && errno == EINTR)
|
||||||
|
{
|
||||||
|
/* We were interrupted by a signal. Either this is
|
||||||
|
because we were interrupted intentionally (i.e. by
|
||||||
|
Thread.interrupt()) or by the GC if it is
|
||||||
|
signal-based. */
|
||||||
|
_Jv_Thread_t *current = _Jv_ThreadCurrentData();
|
||||||
|
if (current->flags & FLAG_INTERRUPTED)
|
||||||
|
{
|
||||||
|
current->flags &= ~(FLAG_INTERRUPTED);
|
||||||
|
done_sleeping = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We were woken up by the GC or another signal. */
|
||||||
|
m2 = java::lang::System::currentTimeMillis ();
|
||||||
|
if (m2 >= m)
|
||||||
|
{
|
||||||
|
r = 0;
|
||||||
|
done_sleeping = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (r && errno == ETIMEDOUT)
|
||||||
|
{
|
||||||
|
/* A timeout is a normal result. */
|
||||||
|
r = 0;
|
||||||
|
done_sleeping = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
done_sleeping = true;
|
||||||
|
}
|
||||||
|
while (! done_sleeping);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -215,6 +258,7 @@ void
|
||||||
_Jv_InitThreads (void)
|
_Jv_InitThreads (void)
|
||||||
{
|
{
|
||||||
pthread_key_create (&_Jv_ThreadKey, NULL);
|
pthread_key_create (&_Jv_ThreadKey, NULL);
|
||||||
|
pthread_key_create (&_Jv_ThreadDataKey, NULL);
|
||||||
pthread_mutex_init (&daemon_mutex, NULL);
|
pthread_mutex_init (&daemon_mutex, NULL);
|
||||||
pthread_cond_init (&daemon_cond, 0);
|
pthread_cond_init (&daemon_cond, 0);
|
||||||
non_daemon_count = 0;
|
non_daemon_count = 0;
|
||||||
|
@ -290,6 +334,7 @@ really_start (void *x)
|
||||||
|
|
||||||
pthread_cleanup_push (throw_cleanup, info->data);
|
pthread_cleanup_push (throw_cleanup, info->data);
|
||||||
pthread_setspecific (_Jv_ThreadKey, info->object);
|
pthread_setspecific (_Jv_ThreadKey, info->object);
|
||||||
|
pthread_setspecific (_Jv_ThreadDataKey, info->data);
|
||||||
info->method (info->object);
|
info->method (info->object);
|
||||||
pthread_cleanup_pop (0);
|
pthread_cleanup_pop (0);
|
||||||
|
|
||||||
|
@ -359,5 +404,6 @@ _Jv_ThreadWait (void)
|
||||||
void
|
void
|
||||||
_Jv_ThreadInterrupt (_Jv_Thread_t *data)
|
_Jv_ThreadInterrupt (_Jv_Thread_t *data)
|
||||||
{
|
{
|
||||||
|
data->flags |= FLAG_INTERRUPTED;
|
||||||
pthread_kill (data->thread, INTR);
|
pthread_kill (data->thread, INTR);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue