d701ba180c745b5e5ab43c26dbe897790c63532e
[multipath-tools/.git] / libmultipath / log_pthread.c
1 /*
2  * Copyright (c) 2005 Christophe Varoqui
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <pthread.h>
8 #include <sys/mman.h>
9
10 #include <memory.h>
11
12 #include "log_pthread.h"
13 #include "log.h"
14 #include "lock.h"
15
16 void log_safe (int prio, const char * fmt, va_list ap)
17 {
18         sigset_t old;
19
20         block_signal(SIGUSR1, &old);
21         block_signal(SIGHUP, NULL);
22
23         pthread_mutex_lock(logq_lock);
24         log_enqueue(prio, fmt, ap);
25         pthread_mutex_unlock(logq_lock);
26
27         pthread_mutex_lock(logev_lock);
28         pthread_cond_signal(logev_cond);
29         pthread_mutex_unlock(logev_lock);
30
31         pthread_sigmask(SIG_SETMASK, &old, NULL);
32 }
33
34 static void flush_logqueue (void)
35 {
36         int empty;
37
38         do {
39                 pthread_mutex_lock(logq_lock);
40                 empty = log_dequeue(la->buff);
41                 pthread_mutex_unlock(logq_lock);
42                 if (!empty)
43                         log_syslog(la->buff);
44         } while (empty == 0);
45 }
46
47 static void * log_thread (void * et)
48 {
49         mlockall(MCL_CURRENT | MCL_FUTURE);
50         logdbg(stderr,"enter log_thread\n");
51
52         while (1) {
53                 pthread_mutex_lock(logev_lock);
54                 pthread_cond_wait(logev_cond, logev_lock);
55                 pthread_mutex_unlock(logev_lock);
56
57                 flush_logqueue();
58         }
59         return NULL;
60 }
61
62 void log_thread_start (pthread_attr_t *attr)
63 {
64         logdbg(stderr,"enter log_thread_start\n");
65
66         logq_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
67         logev_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
68         logev_cond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
69
70         pthread_mutex_init(logq_lock, NULL);
71         pthread_mutex_init(logev_lock, NULL);
72         pthread_cond_init(logev_cond, NULL);
73
74         if (log_init("multipathd", 0)) {
75                 fprintf(stderr,"can't initialize log buffer\n");
76                 exit(1);
77         }
78         pthread_create(&log_thr, attr, log_thread, NULL);
79
80         return;
81 }
82
83 void log_thread_stop (void)
84 {
85         logdbg(stderr,"enter log_thread_stop\n");
86
87         pthread_mutex_lock(logq_lock);
88         pthread_cancel(log_thr);
89         pthread_mutex_unlock(logq_lock);
90         pthread_join(log_thr, NULL);
91
92         flush_logqueue();
93
94         pthread_mutex_destroy(logq_lock);
95         pthread_mutex_destroy(logev_lock);
96         pthread_cond_destroy(logev_cond);
97
98         free(logq_lock);
99         logq_lock = NULL;
100         free(logev_lock);
101         logev_lock = NULL;
102         free(logev_cond);
103         logev_cond = NULL;
104         free_logarea();
105 }