int pn_selector_select(pn_selector_t *selector, int timeout) { assert(selector); pn_error_clear(selector->error); pn_timestamp_t deadline = 0; pn_timestamp_t now = pn_i_now(); if (timeout) { if (selector->deadlines_head) deadline = selector->deadlines_head->deadline; } if (deadline) { int64_t delta = deadline - now; if (delta < 0) { delta = 0; } if (timeout < 0) timeout = delta; else if (timeout > delta) timeout = delta; } deadline = (timeout >= 0) ? now + timeout : 0; // Process all currently available completions, even if matched events available pni_iocp_drain_completions(selector->iocp); pni_zombie_check(selector->iocp, now); // Loop until an interested event is matched, or until deadline while (true) { if (selector->triggered_list_head) break; if (deadline && deadline <= now) break; pn_timestamp_t completion_deadline = deadline; pn_timestamp_t zd = pni_zombie_deadline(selector->iocp); if (zd) completion_deadline = completion_deadline ? pn_min(zd, completion_deadline) : zd; int completion_timeout = (!completion_deadline) ? -1 : completion_deadline - now; int rv = pni_iocp_wait_one(selector->iocp, completion_timeout, selector->error); if (rv < 0) return pn_error_code(selector->error); now = pn_i_now(); if (zd && zd <= now) { pni_zombie_check(selector->iocp, now); } } selector->current = 0; selector->awoken = now; for (iocpdesc_t *iocpd = selector->deadlines_head; iocpd; iocpd = iocpd->deadlines_next) { if (iocpd->deadline <= now) pni_events_update(iocpd, iocpd->events | PN_EXPIRED); else break; } selector->current_triggered = selector->triggered_list_head; return pn_error_code(selector->error); }
int pn_error_set(pn_error_t *error, int code, const char *text) { pn_error_clear(error); if (code) { error->code = code; error->text = pn_strdup(text); } return code; }
int pn_error_copy(pn_error_t *error, pn_error_t *src) { assert(error); if (src) { return pn_error_set(error, pn_error_code(src), pn_error_text(src)); } else { pn_error_clear(error); return 0; } }