static void mm_event_kqueue_poll(struct mm_event_kqueue *event_backend, mm_timeout_t timeout) { ENTER(); DEBUG("poll: changes: %d, timeout: %lu", event_backend->nevents, (unsigned long) timeout); // Calculate the event wait timeout. struct timespec ts; ts.tv_sec = timeout / 1000000; ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a possible sleep. mm_log_relay(); // Poll the system for events. int n = kevent(event_backend->event_fd, event_backend->events, event_backend->nevents, event_backend->events, MM_EVENT_KQUEUE_NEVENTS, &ts); DEBUG("kevent changed: %d, received: %d", event_backend->nevents, n); if (n < 0) { if (errno == EINTR) mm_warning(errno, "kevent"); else mm_error(errno, "kevent"); event_backend->nevents = 0; } else { event_backend->nevents = n; } LEAVE(); }
void mm_libcall(const char *name) { static __thread int recursion_guard = 0; if (!recursion_guard) { ++recursion_guard; mm_warning(0, "attempt to call a standard library function " "overridden by MainMemory: '%s'", name); --recursion_guard; } }
static mm_value_t mc_reader_routine(struct mm_work *work) { ENTER(); struct mm_net_socket *sock = mm_net_reader_socket(work); struct mc_state *state = containerof(sock, struct mc_state, sock.sock); // Try to get some input w/o blocking. mm_net_set_read_timeout(&state->sock.sock, 0); ssize_t n = mm_netbuf_fill(&state->sock, 1); mm_net_set_read_timeout(&state->sock.sock, MC_READ_TIMEOUT); retry: // Get out of here if there is no more input available. if (n <= 0) { if (n == 0 || (errno != EAGAIN && errno != ETIMEDOUT)) state->error = true; // If the socket is closed queue a quit command. if (state->error && !mm_net_is_reader_shutdown(sock)) { struct mc_command *command = mc_command_create(state); command->type = &mc_command_ascii_quit; mc_process_command(state, command); } goto leave; } // Initialize the parser. struct mm_buffer_reader safepoint; mm_netbuf_capture_read_pos(&state->sock, &safepoint); mc_protocol_t protocol = mc_getprotocol(state); state->command = NULL; // Try to parse the received input. bool rc; parse: if (protocol == MC_PROTOCOL_BINARY) rc = mc_binary_parse(state); else rc = mc_parser_parse(state); if (!rc) { if (state->command != NULL) { mc_command_destroy(state->command); state->command = NULL; } if (state->trash) { mm_netbuf_reset(&state->sock); mm_warning(0, "disconnect an odd client"); goto leave; } // The input is incomplete, try to get some more. mm_netbuf_restore_read_pos(&state->sock, &safepoint); n = mm_netbuf_fill(&state->sock, 1); goto retry; } // Process the parsed command. mc_process_command(state, state->command); // If there is more input in the buffer then try to parse // the next command. if (!mm_netbuf_empty(&state->sock)) { state->command = NULL; // Update the safe consumed input position. mm_netbuf_capture_read_pos(&state->sock, &safepoint); goto parse; } // Transmit buffered results and compact the output buffer storage. mm_netbuf_flush(&state->sock); mm_netbuf_compact_write_buf(&state->sock); // Compact the input buffer storage. mm_netbuf_compact_read_buf(&state->sock); leave: LEAVE(); return 0; }