sysvinit/showconsole-1.16-glibc.dif

123 lines
3.0 KiB
Plaintext

--- libconsole.c
+++ libconsole.c 2012-08-02 11:45:26.456510085 +0000
@@ -358,7 +358,9 @@ static void sigio(int sig)
*/
typedef struct _mutex {
- int locked;
+ volatile int locked;
+ volatile int canceled;
+ volatile int used;
pthread_mutex_t mutex;
pthread_t thread;
} mutex_t;
@@ -380,8 +382,8 @@ static inline void unlock(mutex_t *mutex
}
}
-static mutex_t llock = { 0, PTHREAD_MUTEX_INITIALIZER, 0 };
-static mutex_t ljoin = { 0, PTHREAD_MUTEX_INITIALIZER, 0 };
+static mutex_t llock = { 0, 0, 1, PTHREAD_MUTEX_INITIALIZER, 0 };
+static mutex_t ljoin = { 0, 0, 1, PTHREAD_MUTEX_INITIALIZER, 0 };
static pthread_cond_t lcond = PTHREAD_COND_INITIALIZER;
static pthread_t lthread;
static volatile int running;
@@ -429,10 +431,14 @@ xout:
static inline void writelog(void)
{
+ int oldstate;
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
lock(&llock);
if (!flog) { /* log file closed, reset buffer */
resetlog();
unlock(&llock);
+ pthread_setcancelstate(oldstate, NULL);
return;
}
clearerr(flog);
@@ -468,11 +474,12 @@ static inline void writelog(void)
fflush(flog);
fdatasync(fileno(flog));
}
+ pthread_setcancelstate(oldstate, NULL);
}
static inline void flushlog(void)
{
- if (running) pthread_cond_broadcast(&lcond);
+ if (ljoin.canceled == 0) pthread_cond_broadcast(&lcond);
}
static inline int poll(int msec, mutex_t *outer)
@@ -495,11 +502,13 @@ static inline int poll(int msec, mutex_t
abstime.tv_nsec = now.tv_usec * 1000;
do {
- int locked = outer->locked;
/* Note: pthread_cond_timedwait() atomically unlocks the mutex */
- outer->locked = 0;
- err = pthread_cond_timedwait(&lcond, &outer->mutex, &abstime);
- outer->locked = locked;
+ if (outer->canceled == 0) {
+ volatile int locked = outer->locked;
+ outer->locked = 0;
+ err = pthread_cond_timedwait(&lcond, &outer->mutex, &abstime);
+ outer->locked = locked;
+ }
} while (err == EINTR);
if (err == ETIMEDOUT || err == EBUSY)
@@ -507,9 +516,9 @@ static inline int poll(int msec, mutex_t
}
#if 0
} else {
- unlock(&ljoin);
+ unlock(&outer->mutex);
pthread_yield();
- lock(&ljoin);
+ lock(&outer->mutex);
#endif
}
@@ -789,6 +798,7 @@ static void *action(void *dummy attribut
unlock(&ljoin);
(void)pthread_sigmask(SIG_SETMASK, &save_oldset, NULL);
+ ljoin.used = 0;
return NULL;
}
@@ -1004,6 +1014,8 @@ void closeIO(void)
(void)tcdrain(c->fd); /* Hold in sync with console */
}
+ flushlog();
+
do {
/*
* Repeat this as long as required,
@@ -1020,14 +1032,19 @@ void closeIO(void)
more_input(&timeout, 1);
(void)tcdrain(fdread);
+ flushlog();
+
} while (timeout.tv_sec || timeout.tv_nsec);
if (running) {
lock(&ljoin);
running = 0;
unlock(&ljoin);
- flushlog();
- pthread_cancel(lthread);
+ ljoin.canceled = 1;
+ pthread_cond_broadcast(&lcond);
+ pthread_yield();
+ if (ljoin.used && lthread)
+ pthread_cancel(lthread);
}
if (flog) {