diff options
Diffstat (limited to 'liblog/fake_log_device.c')
-rw-r--r-- | liblog/fake_log_device.c | 41 |
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 | */ |
98 | static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER; | 99 | static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER; |
99 | 100 | ||
100 | static void lock() | 101 | static 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 | ||
105 | static void unlock() | 114 | static 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) | |||
154 | static void deleteFakeFd(int fd) | 170 | static 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, | |||
548 | static ssize_t logWritev(int fd, const struct iovec* vector, int count) | 565 | static 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 | ||
600 | bail: | 618 | bail: |
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; |
603 | error: | 621 | error: |
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 | } |