static void process_interrupt_messages (void) { /* Reads all of the interrupts out of the interrupt queue, and sets the corresponding bits in the interrupt word. */ while (1) { msg_t * message = (read_subqueue (OS2_interrupt_qid_local)); if (message == 0) break; switch (MSG_TYPE (message)) { case mt_console_interrupt: tty_set_next_interrupt_char (SM_CONSOLE_INTERRUPT_CODE (message)); break; case mt_timer_event: request_timer_interrupt (); break; default: OS2_logic_error ("Illegal message type in interrupt queue."); break; } OS2_destroy_message (message); } }
void OS2_close_qid (qid_t qid) { OS2_request_mutex_semaphore (QID_LOCK (qid)); while (1) { msg_t * msg = (OS2_msg_fifo_remove (QID_SUBQUEUE (qid))); if (msg == 0) break; OS2_destroy_message (msg); } OS2_destroy_msg_fifo (QID_SUBQUEUE (qid)); (QID_FILTER (qid)) = 0; (QID_TQUEUE (qid)) = 0; (QID_SUBQUEUE (qid)) = 0; OS2_release_mutex_semaphore (QID_LOCK (qid)); OS2_request_mutex_semaphore (qid_lock); { qid_t twin = (QID_TWIN (qid)); if (twin != QID_NONE) { (QID_TWIN (twin)) = QID_NONE; (QID_TWIN (qid)) = QID_NONE; } } (QID_ALLOCATEDP (qid)) = 0; OS2_release_mutex_semaphore (qid_lock); }
void OS2_close_std_tqueue (tqueue_t * tqueue) { OS2_close_event_semaphore (STD_TQUEUE_EVENT (tqueue)); OS2_close_mutex_semaphore (STD_TQUEUE_MUTEX (tqueue)); while (1) { msg_t * msg = (OS2_msg_fifo_remove (STD_TQUEUE_FIFO (tqueue))); if (msg == 0) break; OS2_destroy_message (msg); } OS_free (tqueue); }
void OS2_close_std_tqueue (tqueue_t * tqueue) { while (1) { msg_t * msg = (read_std_tqueue_1 (tqueue, 0)); if (msg == 0) break; OS2_destroy_message (msg); } OS2_close_queue (STD_TQUEUE_FIFO (tqueue)); OS2_close_event_semaphore (STD_TQUEUE_EVENT (tqueue)); OS_free (tqueue); }
static void write_subqueue (msg_t * message) { qid_t qid = (MSG_SENDER (message)); qid_receive_filter_t filter = (QID_FILTER (qid)); if (filter != 0) { message = ((* filter) (message)); if (message == 0) return; } OS2_request_mutex_semaphore (QID_LOCK (qid)); if (QID_SUBQUEUE (qid)) OS2_msg_fifo_insert ((QID_SUBQUEUE (qid)), message); else /* If subqueue is gone, qid has been closed. */ OS2_destroy_message (message); OS2_release_mutex_semaphore (QID_LOCK (qid)); }
static msg_t * input_pipe_reader (LHANDLE handle, qid_t qid, msg_t * message, int * eofp) { ULONG nread; APIRET rc = (dos_read (handle, (SM_READAHEAD_DATA (message)), (sizeof (SM_READAHEAD_DATA (message))), (& nread))); if (rc == NO_ERROR) { (SM_READAHEAD_SIZE (message)) = nread; (*eofp) = (nread == 0); return (message); } OS2_destroy_message (message); if (rc == ERROR_INVALID_HANDLE) /* Handle was closed on us -- no need to do anything else. */ return (0); (*eofp) = (rc == ERROR_BROKEN_PIPE); return (OS2_make_syscall_error (rc, syscall_dos_read)); }
void OS2_send_message (qid_t qid, msg_t * message) { qid_t twin = (QID_TWIN (qid)); tqueue_t * tqueue; if ((twin == QID_NONE) || ((tqueue = (QID_TQUEUE (twin))) == 0)) /* Other end of connection has been closed, so discard the message. We used to signal an error here, but this can happen pretty easily when closing windows or exiting Scheme. The only way to avoid this is to force synchronization of communicating threads, which can be tricky. For example, when closing a PM window, it's not obvious when the last message will be generated by the PM thread. So it's just simpler to ignore messages after the receiver decides it's no longer interested in them. */ OS2_destroy_message (message); else { (MSG_SENDER (message)) = twin; write_tqueue (tqueue, message); } }