cmogstored.git  about / heads / tags
alternative mogstored implementation for MogileFS
blob 35450169cd4467015180a62989ef5c19fad96cc9 1290 bytes (raw)
$ git show HEAD:sig.c	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 
/*
 * Copyright (C) 2012-2020 all contributors <cmogstored-public@yhbt.net>
 * License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 */
#include "cmogstored.h"

/*
 * we block signals in pool threads, only the main thread receives signals
 */

static sigset_t fullset;
sigset_t mog_emptyset;

__attribute__((constructor)) static void sig_init(void)
{
	CHECK(int, 0, sigfillset(&fullset));
	CHECK(int, 0, sigemptyset(&mog_emptyset));
}

void mog_intr_disable(void)
{
	CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &fullset, NULL));
}

void mog_intr_enable(void)
{
	CHECK(int, 0, pthread_sigmask(SIG_SETMASK, &mog_emptyset, NULL));
}

static int sleeper(struct timespec *tsp, const sigset_t *sigmask)
{
	int err = 0;

	/*
	 * pselect is a cancellation point,
	 * ppoll is not POSIX and is only a cancellation point on glibc.
	 */
	if (pselect(0, NULL, NULL, NULL, tsp, sigmask) < 0) {
		err = errno;
		assert((err == EINTR || err == ENOMEM) &&
		       "BUG in pselect usage");
	}
	return err;
}

/* thread-safe, interruptible sleep, negative seconds -> sleep forever */
int mog_sleep(long seconds)
{
	struct timespec ts;
	struct timespec *tsp;

	if (seconds < 0) {
		tsp = NULL;
	} else {
		ts.tv_sec = seconds;
		ts.tv_nsec = 0;
		tsp = &ts;
	}

	return sleeper(tsp, &mog_emptyset);
}

git clone https://yhbt.net/cmogstored.git