multipath-tools: memory.h is referred to the local header
[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 <syslog.h>
8 #include <pthread.h>
9 #include <sys/mman.h>
10
11 #include "memory.h"
12
13 #include "log_pthread.h"
14 #include "log.h"
15 #include "lock.h"
16
17 pthread_t log_thr;
18
19 pthread_mutex_t logq_lock;
20 pthread_mutex_t logev_lock;
21 pthread_cond_t logev_cond;
22
23 int logq_running;
24
25 void log_safe (int prio, const char * fmt, va_list ap)
26 {
27         if (log_thr == (pthread_t)0) {
28                 vsyslog(prio, fmt, ap);
29                 return;
30         }
31
32         pthread_mutex_lock(&logq_lock);
33         log_enqueue(prio, fmt, ap);
34         pthread_mutex_unlock(&logq_lock);
35
36         pthread_mutex_lock(&logev_lock);
37         pthread_cond_signal(&logev_cond);
38         pthread_mutex_unlock(&logev_lock);
39 }
40
41 void log_thread_flush (void)
42 {
43         int empty;
44
45         do {
46                 pthread_mutex_lock(&logq_lock);
47                 empty = log_dequeue(la->buff);
48                 pthread_mutex_unlock(&logq_lock);
49                 if (!empty)
50                         log_syslog(la->buff);
51         } while (empty == 0);
52 }
53
54 static void flush_logqueue (void)
55 {
56         int empty;
57
58         do {
59                 pthread_mutex_lock(&logq_lock);
60                 empty = log_dequeue(la->buff);
61                 pthread_mutex_unlock(&logq_lock);
62                 if (!empty)
63                         log_syslog(la->buff);
64         } while (empty == 0);
65 }
66
67 static void * log_thread (void * et)
68 {
69         int running;
70
71         pthread_mutex_lock(&logev_lock);
72         logq_running = 1;
73         pthread_mutex_unlock(&logev_lock);
74
75         mlockall(MCL_CURRENT | MCL_FUTURE);
76         logdbg(stderr,"enter log_thread\n");
77
78         while (1) {
79                 pthread_mutex_lock(&logev_lock);
80                 pthread_cond_wait(&logev_cond, &logev_lock);
81                 running = logq_running;
82                 pthread_mutex_unlock(&logev_lock);
83                 if (!running)
84                         break;
85                 log_thread_flush();
86         }
87         return NULL;
88 }
89
90 void log_thread_start (pthread_attr_t *attr)
91 {
92         logdbg(stderr,"enter log_thread_start\n");
93
94         pthread_mutex_init(&logq_lock, NULL);
95         pthread_mutex_init(&logev_lock, NULL);
96         pthread_cond_init(&logev_cond, NULL);
97
98         if (log_init("multipathd", 0)) {
99                 fprintf(stderr,"can't initialize log buffer\n");
100                 exit(1);
101         }
102         if (pthread_create(&log_thr, attr, log_thread, NULL)) {
103                 fprintf(stderr,"can't start log thread\n");
104                 exit(1);
105         }
106
107         return;
108 }
109
110 void log_thread_stop (void)
111 {
112         logdbg(stderr,"enter log_thread_stop\n");
113
114         pthread_mutex_lock(&logev_lock);
115         logq_running = 0;
116         pthread_cond_signal(&logev_cond);
117         pthread_mutex_unlock(&logev_lock);
118
119         pthread_mutex_lock(&logq_lock);
120         pthread_cancel(log_thr);
121         pthread_mutex_unlock(&logq_lock);
122         pthread_join(log_thr, NULL);
123         log_thr = (pthread_t)0;
124
125         flush_logqueue();
126
127         pthread_mutex_destroy(&logq_lock);
128         pthread_mutex_destroy(&logev_lock);
129         pthread_cond_destroy(&logev_cond);
130
131         log_close();
132 }