summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'liblog/fake_log_device.c')
-rw-r--r--liblog/fake_log_device.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index 8a8ece250..fcdb6c928 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -24,6 +24,7 @@
24#include <ctype.h> 24#include <ctype.h>
25#include <errno.h> 25#include <errno.h>
26#include <fcntl.h> 26#include <fcntl.h>
27#include <signal.h>
27#include <stdlib.h> 28#include <stdlib.h>
28#include <string.h> 29#include <string.h>
29 30
@@ -97,18 +98,33 @@ typedef struct LogState {
97 */ 98 */
98static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER; 99static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER;
99 100
100static void lock() 101static void lock(sigset_t *sigflags)
101{ 102{
103 /*
104 * If we trigger a signal handler in the middle of locked activity and the
105 * signal handler logs a message, we could get into a deadlock state.
106 */
107 sigset_t all;
108
109 sigfillset(&all);
110 pthread_sigmask(SIG_BLOCK, &all, sigflags);
102 pthread_mutex_lock(&fakeLogDeviceLock); 111 pthread_mutex_lock(&fakeLogDeviceLock);
103} 112}
104 113
105static void unlock() 114static void unlock(sigset_t *sigflags)
106{ 115{
107 pthread_mutex_unlock(&fakeLogDeviceLock); 116 pthread_mutex_unlock(&fakeLogDeviceLock);
117 pthread_sigmask(SIG_UNBLOCK, sigflags, NULL);
108} 118}
119
120#define DECLARE_SIGSET(name) sigset_t name
121
109#else // !defined(_WIN32) 122#else // !defined(_WIN32)
110#define lock() ((void)0) 123
111#define unlock() ((void)0) 124#define lock(sigflags) ((void)0)
125#define unlock(sigflags) ((void)0)
126#define DECLARE_SIGSET(name)
127
112#endif // !defined(_WIN32) 128#endif // !defined(_WIN32)
113 129
114 130
@@ -154,8 +170,9 @@ static LogState *fdToLogState(int fd)
154static void deleteFakeFd(int fd) 170static void deleteFakeFd(int fd)
155{ 171{
156 LogState *ls; 172 LogState *ls;
173 DECLARE_SIGSET(sigflags);
157 174
158 lock(); 175 lock(&sigflags);
159 176
160 ls = fdToLogState(fd); 177 ls = fdToLogState(fd);
161 if (ls != NULL) { 178 if (ls != NULL) {
@@ -164,7 +181,7 @@ static void deleteFakeFd(int fd)
164 free(ls); 181 free(ls);
165 } 182 }
166 183
167 unlock(); 184 unlock(&sigflags);
168} 185}
169 186
170/* 187/*
@@ -548,12 +565,13 @@ static void showLog(LogState *state,
548static ssize_t logWritev(int fd, const struct iovec* vector, int count) 565static ssize_t logWritev(int fd, const struct iovec* vector, int count)
549{ 566{
550 LogState* state; 567 LogState* state;
568 DECLARE_SIGSET(sigflags);
551 569
552 /* Make sure that no-one frees the LogState while we're using it. 570 /* Make sure that no-one frees the LogState while we're using it.
553 * Also guarantees that only one thread is in showLog() at a given 571 * Also guarantees that only one thread is in showLog() at a given
554 * time (if it matters). 572 * time (if it matters).
555 */ 573 */
556 lock(); 574 lock(&sigflags);
557 575
558 state = fdToLogState(fd); 576 state = fdToLogState(fd);
559 if (state == NULL) { 577 if (state == NULL) {
@@ -598,10 +616,10 @@ static ssize_t logWritev(int fd, const struct iovec* vector, int count)
598 } 616 }
599 617
600bail: 618bail:
601 unlock(); 619 unlock(&sigflags);
602 return vector[0].iov_len + vector[1].iov_len + vector[2].iov_len; 620 return vector[0].iov_len + vector[1].iov_len + vector[2].iov_len;
603error: 621error:
604 unlock(); 622 unlock(&sigflags);
605 return -1; 623 return -1;
606} 624}
607 625
@@ -621,8 +639,9 @@ static int logOpen(const char* pathName, int flags __unused)
621{ 639{
622 LogState *logState; 640 LogState *logState;
623 int fd = -1; 641 int fd = -1;
642 DECLARE_SIGSET(sigflags);
624 643
625 lock(); 644 lock(&sigflags);
626 645
627 logState = createLogState(); 646 logState = createLogState();
628 if (logState != NULL) { 647 if (logState != NULL) {
@@ -632,7 +651,7 @@ static int logOpen(const char* pathName, int flags __unused)
632 errno = ENFILE; 651 errno = ENFILE;
633 } 652 }
634 653
635 unlock(); 654 unlock(&sigflags);
636 655
637 return fd; 656 return fd;
638} 657}