+static int interrupt_pipe_enabled = 0;
+static pthread_key_t interrupt_pipe_key;
+
+void
+res_delete_interrupt_token(void *token)
+{
+ int *interrupt_pipe;
+
+ interrupt_pipe = token;
+ if (interrupt_pipe == NULL) return;
+
+ if (interrupt_pipe[0] >= 0)
+ {
+ close(interrupt_pipe[0]);
+ interrupt_pipe[0] = -1;
+ }
+
+ if (interrupt_pipe[1] >= 0)
+ {
+ close(interrupt_pipe[1]);
+ interrupt_pipe[1] = -1;
+ }
+
+ pthread_setspecific(interrupt_pipe_key, NULL);
+ free(interrupt_pipe);
+}
+
+void *
+res_init_interrupt_token(void)
+{
+ int *interrupt_pipe;
+
+ interrupt_pipe = (int *)malloc(2 * sizeof(int));
+ if (interrupt_pipe == NULL) return NULL;
+
+ if (pipe(interrupt_pipe) < 0)
+ {
+ /* this shouldn't happen */
+ interrupt_pipe[0] = -1;
+ interrupt_pipe[1] = -1;
+ }
+ else
+ {
+ fcntl(interrupt_pipe[0], F_SETFD, FD_CLOEXEC | O_NONBLOCK);
+ fcntl(interrupt_pipe[1], F_SETFD, FD_CLOEXEC | O_NONBLOCK);
+ }
+
+ pthread_setspecific(interrupt_pipe_key, interrupt_pipe);
+
+ return interrupt_pipe;
+}
+
+void
+res_interrupt_requests_enable(void)
+{
+ interrupt_pipe_enabled = 1;
+ pthread_key_create(&interrupt_pipe_key, NULL);
+}
+
+void
+res_interrupt_requests_disable(void)
+{
+ interrupt_pipe_enabled = 0;
+ pthread_key_delete(interrupt_pipe_key);
+}
+
+void
+res_interrupt_request(void *token)
+{
+ int oldwrite;
+ int *interrupt_pipe;
+
+ interrupt_pipe = token;
+
+ if ((interrupt_pipe == NULL) || (interrupt_pipe_enabled == 0)) return;
+
+ oldwrite = interrupt_pipe[1];
+ interrupt_pipe[1] = -1;
+
+ if (oldwrite >= 0) close(oldwrite);
+}