📄 su_win32_port.c
字号:
if (n != j) { assert(reverses[j] > 0); assert(indices[reverses[j]] == j); indices[reverses[j]] = n; reverses[n] = reverses[j]; self->sup_waits[n] = self->sup_waits[j]; self->sup_wait_cbs[n] = self->sup_wait_cbs[j]; self->sup_wait_args[n] = self->sup_wait_args[j]; self->sup_wait_roots[n] = self->sup_wait_roots[j]; n = j; } } if (n < N) { assert(reverses[N] > 0); assert(indices[reverses[N]] == N); indices[reverses[N]] = n; reverses[n] = reverses[N]; self->sup_waits[n] = self->sup_waits[N]; self->sup_wait_cbs[n] = self->sup_wait_cbs[N]; self->sup_wait_args[n] = self->sup_wait_args[N]; self->sup_wait_roots[n] = self->sup_wait_roots[N]; n = N; } reverses[n] = -1; memset(&self->sup_waits[n], 0, sizeof self->sup_waits[n]); self->sup_wait_cbs[n] = NULL; self->sup_wait_args[n] = NULL; self->sup_wait_roots[n] = NULL; indices[i] = indices[0]; indices[0] = -i; self->sup_registers++; return i;}/** Unregister a su_wait_t object. * * Unregisters a su_wait_t object. The wait object, a callback function and * a argument are removed from the port object. * * @param self - pointer to port object * @param root - pointer to root object * @param wait - pointer to wait object * @param callback - callback function pointer (may be NULL) * @param arg - argument given to callback function when it is invoked * (may be NULL) * * @deprecated Use su_wsevent_port_deregister() instead. * * @return Nonzero index of the wait object, or -1 upon an error. */int su_wsevent_port_unregister(su_port_t *self, su_root_t *root, su_wait_t *wait, su_wakeup_f callback, /* XXX - ignored */ su_wakeup_arg_t *arg){ int n, N; assert(self); assert(su_port_own_thread(self)); N = self->sup_n_waits; for (n = 0; n < N; n++) { if (SU_WAIT_CMP(wait[0], self->sup_waits[n]) == 0) { return su_wsevent_port_deregister0(self, self->sup_reverses[n], 0); } } su_seterrno(ENOENT); return -1;}/** Deregister a su_wait_t object. * * Deregisters a registration by index. The wait object, a callback * function and a argument are removed from the port object. The wait * object is destroyed. * * @param self - pointer to port object * @param i - registration index * * @return Index of the wait object, or -1 upon an error. */int su_wsevent_port_deregister(su_port_t *self, int i){ su_wait_t wait[1] = { SU_WAIT_INIT }; int retval; assert(self); assert(su_port_own_thread(self)); if (i <= 0 || i > self->sup_size_waits) return su_seterrno(EBADF); if (self->sup_indices[i] < 0) return su_seterrno(EBADF); retval = su_wsevent_port_deregister0(self, i, 1); su_wait_destroy(wait); return retval;}/** @internal * Unregister all su_wait_t objects. * * Unregisters all su_wait_t objects and destroys all queued timers * associated with given root object. * * @param self - pointer to port object * @param root - pointer to root object * * @return Number of wait objects removed. */int su_wsevent_port_unregister_all(su_port_t *self, su_root_t *root){ int i, j, index, N; int *indices, *reverses; su_wait_t *waits; su_wakeup_f *wait_cbs; su_wakeup_arg_t**wait_args; su_root_t **wait_roots; assert(su_port_own_thread(self)); N = self->sup_n_waits; indices = self->sup_indices; reverses = self->sup_reverses; waits = self->sup_waits; wait_cbs = self->sup_wait_cbs; wait_args = self->sup_wait_args; wait_roots = self->sup_wait_roots; for (i = j = 0; i < N; i++) { index = reverses[i]; assert(index > 0 && indices[index] == i); if (wait_roots[i] == root) { /* XXX - we should free all resources associated with this, too */ if (i < self->sup_pri_offset) self->sup_pri_offset--; indices[index] = indices[0]; indices[0] = -index; continue; } if (i != j) { indices[index] = j; reverses[j] = reverses[i]; waits[j] = waits[i]; wait_cbs[j] = wait_cbs[i]; wait_args[j] = wait_args[i]; wait_roots[j] = wait_roots[i]; } j++; } for (i = j; i < N; i++) { reverses[i] = -1; wait_cbs[i] = NULL; wait_args[i] = NULL; wait_roots[i] = NULL; } memset(&waits[j], 0, (char *)&waits[N] - (char *)&waits[j]); self->sup_n_waits = j; self->sup_registers++; return N - j;}/**Set mask for a registered event. @internal * * Sets the mask describing events that can signal the registered callback. * * @param port pointer to port object * @param index registration index * @param socket socket * @param events new event mask * * @retval 0 when successful, * @retval -1 upon an error. */int su_wsevent_port_eventmask(su_port_t *self, int index, int socket, int events){ int n; assert(self); assert(su_port_own_thread(self)); if (index <= 0 || index > self->sup_size_waits) return su_seterrno(EBADF); n = self->sup_indices[index]; if (n < 0) return su_seterrno(EBADF); return su_wait_mask(&self->sup_waits[n], socket, events);}/** @internal Enable multishot mode. * * Enables, disables or queries the multishot mode for the port. The * multishot mode determines how the events are scheduled by port. If * multishot mode is enabled, port serves all the sockets that have received * network events. If it is disabled, only first socket event is served. * * @param self pointer to port object * @param multishot multishot mode (0 => disables, 1 => enables, -1 => query) * * @retval 0 multishot mode is disabled * @retval 1 multishot mode is enabled * @retval -1 an error occurred */staticint su_wsevent_port_multishot(su_port_t *self, int multishot){ if (multishot < 0) return self->sup_multishot; else if (multishot == 0 || multishot == 1) return self->sup_multishot = multishot; else return (errno = EINVAL), -1;}/** @internal * Wait (poll()) for wait objects in port. * * @param self pointer to port * @param tout timeout in milliseconds * * @return number of events handled */staticint su_wsevent_port_wait_events(su_port_t *self, su_duration_t tout){ int i, events = 0; su_wait_t *waits = self->sup_waits; int n = self->sup_n_waits; su_root_t *root; i = su_wait(waits, (unsigned)n, tout); if (i >= 0 && i < n) {#if 0 /* poll() can return events for multiple wait objects */ if (self->sup_multishot) { unsigned version = self->sup_registers; for (; i < n; i++) { if (waits[i].revents) { root = self->sup_wait_roots[i]; self->sup_wait_cbs[i](root ? su_root_magic(root) : NULL, &waits[i], self->sup_wait_args[i]); events++; /* Callback function used su_register()/su_deregister() */ if (version != self->sup_registers) break; } } }#else if (0) ;#endif else { root = self->sup_wait_roots[i]; self->sup_wait_cbs[i](root ? su_root_magic(root) : NULL, &self->sup_waits[i], self->sup_wait_args[i]); events++; } } return events;}/** Create a port using WSAEVENTs and WSAWaitForMultipleEvents. */su_port_t *su_wsaevent_port_create(void){ su_port_t *self = su_home_new(sizeof *self); if (!self) return self; if (su_home_destructor(su_port_home(self), su_wsevent_port_deinit) < 0) return su_home_unref(su_port_home(self)), NULL; self->sup_multishot = SU_ENABLE_MULTISHOT_POLL; if (su_socket_port_init(self->sup_base, su_wsevent_port_vtable) < 0) return su_home_unref(su_port_home(self)), NULL; return self;}int su_wsaevent_clone_start(su_root_t *parent, su_clone_r return_clone, su_root_magic_t *magic, su_root_init_f init, su_root_deinit_f deinit){ return su_pthreaded_port_start(su_wsaevent_port_create, parent, return_clone, magic, init, deinit);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -