2 * Copyright (c) 2002-2006 MontaVista Software, Inc.
3 * Copyright (c) 2006 Sun Microsystems, Inc.
4 * Copyright (c) 2006-2007 Red Hat, Inc.
8 * Author: Steven Dake (sdake@mvista.com)
10 * This software licensed under BSD license, the text of which follows:
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * - Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * - Neither the name of the MontaVista Software, Inc. nor the names of its
21 * contributors may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGE.
40 #include <sys/types.h>
44 #include <sys/socket.h>
47 #include <sys/resource.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
60 #include "../include/saAis.h"
61 #include "../include/list.h"
62 #include "../include/queue.h"
63 #include "../lcr/lcr_ifact.h"
68 #include "mainconfig.h"
69 #include "totemconfig.h"
77 #define LOG_SERVICE LOG_SERVICE_IPC
82 #define SERVER_BACKLOG 5
84 static pthread_mutex_t timer_mutex
= PTHREAD_MUTEX_INITIALIZER
;
86 static pthread_t expiry_thread
;
88 static pthread_attr_t thread_attr
;
90 static struct timerlist timers_timerlist
;
92 static void (*timer_serialize_lock_fn
) (void);
94 static void (*timer_serialize_unlock_fn
) (void);
96 static void *prioritized_timer_thread (void *data
);
98 extern void pthread_exit(void *) __attribute__((noreturn
));
101 * This thread runs at the highest priority to run system wide timers
103 static void *prioritized_timer_thread (void *data
)
106 unsigned long long timeout
;
108 #if ! defined(TS_CLASS) && (defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS))
109 struct sched_param sched_param
;
112 sched_param
.sched_priority
= 2;
113 res
= pthread_setschedparam (expiry_thread
, SCHED_RR
, &sched_param
);
116 pthread_mutex_unlock (&timer_mutex
);
119 timer_serialize_lock_fn ();
120 timeout
= timerlist_msec_duration_to_expire (&timers_timerlist
);
121 if (timeout
!= -1 && timeout
> 0xFFFFFFFF) {
122 timeout
= 0xFFFFFFFE;
124 timer_serialize_unlock_fn ();
125 fds
= poll (NULL
, 0, timeout
);
129 pthread_mutex_lock (&timer_mutex
);
130 timer_serialize_lock_fn ();
132 timerlist_expire (&timers_timerlist
);
134 timer_serialize_unlock_fn ();
135 pthread_mutex_unlock (&timer_mutex
);
141 static void sigusr1_handler (int num
) {
142 #ifdef OPENAIS_SOLARIS
143 /* Rearm the signal facility */
144 signal (num
, sigusr1_handler
);
148 int openais_timer_init (
149 void (*serialize_lock_fn
) (void),
150 void (*serialize_unlock_fn
) (void))
154 timer_serialize_lock_fn
= serialize_lock_fn
;
155 timer_serialize_unlock_fn
= serialize_unlock_fn
;
157 timerlist_init (&timers_timerlist
);
159 signal (SIGUSR1
, sigusr1_handler
);
161 pthread_mutex_lock (&timer_mutex
);
162 pthread_attr_init (&thread_attr
);
163 pthread_attr_setstacksize (&thread_attr
, 100000);
164 pthread_attr_setdetachstate (&thread_attr
, PTHREAD_CREATE_DETACHED
);
165 res
= pthread_create (&expiry_thread
, &thread_attr
,
166 prioritized_timer_thread
, NULL
);
171 int openais_timer_add_absolute (
172 unsigned long long nanosec_from_epoch
,
174 void (*timer_fn
) (void *data
),
175 timer_handle
*handle
)
180 if (pthread_equal (pthread_self(), expiry_thread
) != 0) {
184 pthread_mutex_lock (&timer_mutex
);
187 res
= timerlist_add_absolute (
195 pthread_mutex_unlock (&timer_mutex
);
198 pthread_kill (expiry_thread
, SIGUSR1
);
203 int openais_timer_add_duration (
204 unsigned long long nanosec_duration
,
206 void (*timer_fn
) (void *data
),
207 timer_handle
*handle
)
212 if (pthread_equal (pthread_self(), expiry_thread
) != 0) {
216 pthread_mutex_lock (&timer_mutex
);
219 res
= timerlist_add_duration (
227 pthread_mutex_unlock (&timer_mutex
);
230 pthread_kill (expiry_thread
, SIGUSR1
);
235 void openais_timer_delete (
236 timer_handle timer_handle
)
240 if (timer_handle
== 0) {
244 if (pthread_equal (pthread_self(), expiry_thread
) != 0) {
248 pthread_mutex_lock (&timer_mutex
);
251 timerlist_del (&timers_timerlist
, timer_handle
);
254 pthread_mutex_unlock (&timer_mutex
);
258 void openais_timer_lock (void)
260 pthread_mutex_lock (&timer_mutex
);
263 void openais_timer_unlock (void)
265 pthread_mutex_unlock (&timer_mutex
);