this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Handle EINTR for a few RPC calls

+57 -3
+32 -1
src/kernel/emulation/linux/mach/mach_traps.c
··· 10 10 #include "../ext/mremap.h" 11 11 #include <darlingserver/rpc.h> 12 12 #include "../simple.h" 13 + #include "../duct_errno.h" 13 14 14 15 #define UNIMPLEMENTED_TRAP() { char msg[] = "Called unimplemented Mach trap: "; write(2, msg, sizeof(msg)-1); write(2, __FUNCTION__, sizeof(__FUNCTION__)-1); write(2, "\n", 1); } 15 16 ··· 66 67 mach_msg_header_t *rcv_msg, 67 68 mach_msg_size_t rcv_limit) 68 69 { 69 - int code = dserver_rpc_mach_msg_overwrite(msg, option, send_size, rcv_size, rcv_name, timeout, notify, rcv_msg); 70 + int code; 71 + 72 + retry: 73 + code = dserver_rpc_mach_msg_overwrite(msg, option, send_size, rcv_size, rcv_name, timeout, notify, rcv_msg); 70 74 71 75 if (code < 0) { 76 + if (code == -LINUX_EINTR) { 77 + // when the RPC call returns EINTR, it means we didn't manage to send the RPC message to the server; 78 + // when the RPC receive operation receives EINTR, it retries the call, meaning we should never see EINTR from an RPC receive. 79 + // therefore, if we wanted to both send and receive a message, this means the send (which is performed first) was interrupted. 80 + // 81 + // we also need to check if the caller wants to know about interrupts. if they want send interrupts, we tell them. 82 + // if they want receive interrupts, we tell them. otherwise, we retry the call. 83 + if ((option & MACH_SEND_MSG) != 0 && (option & MACH_SEND_INTERRUPT) != 0) { 84 + return MACH_SEND_INTERRUPTED; 85 + } else if ((option & MACH_RCV_MSG) != 0 && (option & MACH_RCV_INTERRUPT) != 0) { 86 + return MACH_RCV_INTERRUPTED; 87 + } else { 88 + goto retry; 89 + } 90 + } 72 91 __simple_printf("mach_msg_overwrite failed (internally): %d\n", code); 73 92 __simple_abort(); 74 93 } ··· 116 135 int code = dserver_rpc_semaphore_wait(wait_name); 117 136 118 137 if (code < 0) { 138 + if (code == -LINUX_EINTR) { 139 + return KERN_ABORTED; 140 + } 119 141 __simple_printf("semaphore_wait failed (internally): %d\n", code); 120 142 __simple_abort(); 121 143 } ··· 130 152 int code = dserver_rpc_semaphore_wait_signal(wait_name, signal_name); 131 153 132 154 if (code < 0) { 155 + if (code == -LINUX_EINTR) { 156 + return KERN_ABORTED; 157 + } 133 158 __simple_printf("semaphore_wait_signal failed (internally): %d\n", code); 134 159 __simple_abort(); 135 160 } ··· 145 170 int code = dserver_rpc_semaphore_timedwait(wait_name, sec, nsec); 146 171 147 172 if (code < 0) { 173 + if (code == -LINUX_EINTR) { 174 + return KERN_ABORTED; 175 + } 148 176 __simple_printf("semaphore_timedwait failed (internally): %d\n", code); 149 177 __simple_abort(); 150 178 } ··· 161 189 int code = dserver_rpc_semaphore_timedwait_signal(wait_name, signal_name, sec, nsec); 162 190 163 191 if (code < 0) { 192 + if (code == -LINUX_EINTR) { 193 + return KERN_ABORTED; 194 + } 164 195 __simple_printf("semaphore_timedwait_signal failed (internally): %d\n", code); 165 196 __simple_abort(); 166 197 }
+4 -1
src/kernel/emulation/linux/psynch/psynch_cvwait.c
··· 3 3 #include <linux-syscalls/linux.h> 4 4 #include <darlingserver/rpc.h> 5 5 #include "../simple.h" 6 - 6 + #include "../duct_errno.h" 7 7 8 8 long sys_psynch_cvwait(void* cv, uint64_t cvlsgen, uint32_t cvugen, void * mutex, uint64_t mugen, 9 9 uint32_t flags, int64_t sec, uint32_t nsec) ··· 12 12 int ret = dserver_rpc_psynch_cvwait(cv, cvlsgen, cvugen, mutex, mugen, flags, sec, nsec, &retval); 13 13 14 14 if (ret < 0) { 15 + if (ret == -LINUX_EINTR) { 16 + return -EINTR; 17 + } 15 18 __simple_printf("psynch_cvwait failed internally: %d", ret); 16 19 __simple_abort(); 17 20 }
+4
src/kernel/emulation/linux/psynch/psynch_mutexwait.c
··· 3 3 #include <linux-syscalls/linux.h> 4 4 #include <darlingserver/rpc.h> 5 5 #include "../simple.h" 6 + #include "../duct_errno.h" 6 7 7 8 long sys_psynch_mutexwait(void* mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags) 8 9 { ··· 10 11 int ret = dserver_rpc_psynch_mutexwait(mutex, mgen, ugen, tid, flags, &retval); 11 12 12 13 if (ret < 0) { 14 + if (ret == -LINUX_EINTR) { 15 + return -EINTR; 16 + } 13 17 __simple_printf("psynch_mutexwait failed internally: %d", ret); 14 18 __simple_abort(); 15 19 }
+4
src/kernel/emulation/linux/psynch/psynch_rw_rdlock.c
··· 3 3 #include <linux-syscalls/linux.h> 4 4 #include <darlingserver/rpc.h> 5 5 #include "../simple.h" 6 + #include "../duct_errno.h" 6 7 7 8 long sys_psynch_rw_rdlock(void* rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags) 8 9 { ··· 10 11 int ret = dserver_rpc_psynch_rw_rdlock(rwlock, lgenval, ugenval, rw_wc, flags, &retval); 11 12 12 13 if (ret < 0) { 14 + if (ret == -LINUX_EINTR) { 15 + return -EINTR; 16 + } 13 17 __simple_printf("psynch_rw_rdlock failed internally: %d", ret); 14 18 __simple_abort(); 15 19 }
+4
src/kernel/emulation/linux/psynch/psynch_rw_wrlock.c
··· 3 3 #include <linux-syscalls/linux.h> 4 4 #include <darlingserver/rpc.h> 5 5 #include "../simple.h" 6 + #include "../duct_errno.h" 6 7 7 8 long sys_psynch_rw_wrlock(void* rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags) 8 9 { ··· 10 11 int ret = dserver_rpc_psynch_rw_wrlock(rwlock, lgenval, ugenval, rw_wc, flags, &retval); 11 12 12 13 if (ret < 0) { 14 + if (ret == -LINUX_EINTR) { 15 + return -EINTR; 16 + } 13 17 __simple_printf("psynch_rw_wrlock failed internally: %d", ret); 14 18 __simple_abort(); 15 19 }
+9 -1
src/kernel/libsyscall/mach/mach_init.c
··· 64 64 65 65 #ifdef DARLING 66 66 #include <darlingserver/rpc.h> 67 + #include "../../emulation/linux/duct_errno.h" 67 68 #endif 68 69 69 70 mach_port_t bootstrap_port = MACH_PORT_NULL; ··· 144 145 145 146 #ifdef DARLING 146 147 int _mach_fork_parent(void) { 147 - if (dserver_rpc_fork_wait_for_child() < 0) { 148 + int result; 149 + 150 + retry: 151 + result = dserver_rpc_fork_wait_for_child(); 152 + if (result < 0) { 153 + if (result == -LINUX_EINTR) { 154 + goto retry; 155 + } 148 156 __builtin_unreachable(); 149 157 } 150 158 return 0;