aboutsummaryrefslogtreecommitdiffstats
path: root/lang/swift510/files/patch-swift-corelibs-libdispatch_src_queue.c
blob: 09d068cd3802e63c1f4a0bf70766e87c8b63e537 (plain) (blame)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
--- swift-corelibs-libdispatch/src/queue.c.orig	2023-06-15 00:55:45 UTC
+++ swift-corelibs-libdispatch/src/queue.c
@@ -6467,7 +6467,7 @@ _dispatch_runloop_handle_is_valid(dispatch_runloop_han
 {
 #if TARGET_OS_MAC
 	return MACH_PORT_VALID(handle);
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__FreeBSD__)
 	return handle >= 0;
 #elif defined(_WIN32)
 	return handle != NULL;
@@ -6482,7 +6482,7 @@ _dispatch_runloop_queue_get_handle(dispatch_lane_t dq)
 {
 #if TARGET_OS_MAC
 	return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt);
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__FreeBSD__)
 	// decode: 0 is a valid fd, so offset by 1 to distinguish from NULL
 	return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt) - 1;
 #elif defined(_WIN32)
@@ -6499,7 +6499,7 @@ _dispatch_runloop_queue_set_handle(dispatch_lane_t dq,
 {
 #if TARGET_OS_MAC
 	dq->do_ctxt = (void *)(uintptr_t)handle;
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__FreeBSD__)
 	// encode: 0 is a valid fd, so offset by 1 to distinguish from NULL
 	dq->do_ctxt = (void *)(uintptr_t)(handle + 1);
 #elif defined(_WIN32)
@@ -6558,6 +6558,37 @@ _dispatch_runloop_queue_handle_init(void *ctxt)
 		}
 	}
 	handle = fd;
+#elif defined(__FreeBSD__)
+	int kq = kqueuex(KQUEUE_CLOEXEC);
+	if (kq == -1) {
+		int err = errno;
+		switch (err) {
+		case EMFILE:
+			DISPATCH_CLIENT_CRASH(err, "kqueuex() failure: "
+					"process is out of file descriptors");
+			break;
+		case ENFILE:
+			DISPATCH_CLIENT_CRASH(err, "kqueuex() failure: "
+					"system is out of file descriptors");
+			break;
+		case ENOMEM:
+			DISPATCH_CLIENT_CRASH(err, "kqueuex() failure: "
+					"kernel is out of memory or the "
+					"RLIMIT_KQUEUES user resource limit "
+					"would be exceeded");
+			break;
+		default:
+			DISPATCH_INTERNAL_CRASH(err, "kqueuex() failure");
+			break;
+		}
+	}
+	struct kevent kev = {
+		.ident = 0, // Must match the value used by Core Foundation.
+		.filter = EVFILT_USER,
+		.flags = EV_ADD | EV_CLEAR,
+	};
+	dispatch_assume_zero(kevent(kq, &kev, 1, NULL, 0, NULL));
+	handle = kq;
 #elif defined(_WIN32)
 	HANDLE hEvent;
 	hEvent = CreateEventW(NULL, /*bManualReset=*/FALSE,
@@ -6589,7 +6620,7 @@ _dispatch_runloop_queue_handle_dispose(dispatch_lane_t
 	kr = mach_port_destruct(mach_task_self(), mp, -1, guard);
 	DISPATCH_VERIFY_MIG(kr);
 	(void)dispatch_assume_zero(kr);
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__FreeBSD__)
 	int rc = close(handle);
 	(void)dispatch_assume_zero(rc);
 #elif defined(_WIN32)
@@ -6628,6 +6659,13 @@ _dispatch_runloop_queue_class_poke(dispatch_lane_t dq)
 		result = eventfd_write(handle, 1);
 	} while (result == -1 && errno == EINTR);
 	(void)dispatch_assume_zero(result);
+#elif defined(__FreeBSD__)
+	struct kevent kev = {
+		.ident = 0, // Must match the value used by Core Foundation.
+		.filter = EVFILT_USER,
+		.fflags = NOTE_TRIGGER,
+	};
+	dispatch_assume_zero(kevent(handle, &kev, 1, NULL, 0, NULL));
 #elif defined(_WIN32)
 	BOOL bSuccess;
 	bSuccess = SetEvent(handle);