static void setup_pollset(abts_case *tc, void *data) { apr_status_t rv; rv = apr_pollset_create_ex(&pollset, LARGE_NUM_SOCKETS, p, 0, default_pollset_impl); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); }
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, apr_uint32_t size, apr_pool_t *p, apr_uint32_t flags) { apr_pollset_method_e method = APR_POLLSET_DEFAULT; return apr_pollset_create_ex(pollset, size, p, flags, method); }
static void pollset_default(abts_case *tc, void *data) { apr_status_t rv1, rv2; apr_pollset_t *pollset; /* verify that APR will successfully create a pollset if an invalid method * is specified as long as APR_POLLSET_NODEFAULT isn't specified * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at * least one create call will succeed after having to switch to the default * type) */ rv1 = apr_pollset_create_ex(&pollset, 1, p, 0, APR_POLLSET_PORT); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1); ABTS_PTR_NOTNULL(tc, pollset); rv1 = apr_pollset_create_ex(&pollset, 1, p, 0, APR_POLLSET_KQUEUE); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv1); ABTS_PTR_NOTNULL(tc, pollset); /* verify that APR will fail to create a pollset if an invalid method is * specified along with APR_POLLSET_NODEFAULT * (no platform has both APR_POLLSET_PORT and APR_POLLSET_KQUEUE, so at * least one create call will fail since it can't switch to the default * type) */ rv1 = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_NODEFAULT, APR_POLLSET_PORT); if (rv1 == APR_SUCCESS) { ABTS_PTR_NOTNULL(tc, pollset); } rv2 = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_NODEFAULT, APR_POLLSET_KQUEUE); if (rv2 == APR_SUCCESS) { ABTS_PTR_NOTNULL(tc, pollset); } ABTS_ASSERT(tc, "failure using APR_POLLSET_NODEFAULT with unsupported method", rv1 != APR_SUCCESS || rv2 != APR_SUCCESS); }
serf_context_t *serf_context_create_ex( void *user_baton, serf_socket_add_t addf, serf_socket_remove_t rmf, apr_pool_t *pool) { serf_context_t *ctx = apr_pcalloc(pool, sizeof(*ctx)); ctx->pool = pool; if (user_baton != NULL) { ctx->pollset_baton = user_baton; ctx->pollset_add = addf; ctx->pollset_rm = rmf; } else { /* build the pollset with a (default) number of connections */ serf_pollset_t *ps = apr_pcalloc(pool, sizeof(*ps)); /* ### TODO: As of APR 1.4.x apr_pollset_create_ex can return a status ### other than APR_SUCCESS, so we should handle it. ### Probably move creation of the pollset to later when we have ### the possibility of returning status to the caller. */ #ifdef BROKEN_WSAPOLL /* APR 1.4.x switched to using WSAPoll() on Win32, but it does not * properly handle errors on a non-blocking sockets (such as * connecting to a server where no listener is active). * * So, sadly, we must force using select() on Win32. * * http://mail-archives.apache.org/mod_mbox/apr-dev/201105.mbox/%[email protected]%3E */ (void) apr_pollset_create_ex(&ps->pollset, MAX_CONN, pool, 0, APR_POLLSET_SELECT); #else (void) apr_pollset_create(&ps->pollset, MAX_CONN, pool, 0); #endif ctx->pollset_baton = ps; ctx->pollset_add = pollset_add; ctx->pollset_rm = pollset_rm; } /* default to a single connection since that is the typical case */ ctx->conns = apr_array_make(pool, 1, sizeof(serf_connection_t *)); /* Initialize progress status */ ctx->progress_read = 0; ctx->progress_written = 0; ctx->authn_types = SERF_AUTHN_ALL; ctx->server_authn_info = apr_hash_make(pool); return ctx; }
static void pollset_wakeup(abts_case *tc, void *data) { apr_status_t rv; apr_pollfd_t socket_pollfd; apr_pollset_t *pollset; apr_int32_t num; const apr_pollfd_t *descriptors; rv = apr_pollset_create_ex(&pollset, 1, p, APR_POLLSET_WAKEABLE, default_pollset_impl); if (rv == APR_ENOTIMPL) { ABTS_NOT_IMPL(tc, "apr_pollset_wakeup() not supported"); return; } ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* send wakeup but no data; apr_pollset_poll() should return APR_EINTR */ rv = apr_pollset_wakeup(pollset); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_pollset_poll(pollset, -1, &num, &descriptors); ABTS_INT_EQUAL(tc, APR_EINTR, rv); /* send wakeup and data; apr_pollset_poll() should return APR_SUCCESS */ socket_pollfd.desc_type = APR_POLL_SOCKET; socket_pollfd.reqevents = APR_POLLIN; socket_pollfd.desc.s = s[0]; socket_pollfd.client_data = s[0]; rv = apr_pollset_add(pollset, &socket_pollfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); send_msg(s, sa, 0, tc); rv = apr_pollset_wakeup(pollset); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_pollset_poll(pollset, -1, &num, &descriptors); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, 1, num); }
apr_status_t run_test_server(serv_ctx_t *servctx, apr_short_interval_time_t duration, apr_pool_t *pool) { apr_status_t status; apr_pollset_t *pollset; apr_int32_t num; const apr_pollfd_t *desc; /* create a new pollset */ #ifdef BROKEN_WSAPOLL status = apr_pollset_create_ex(&pollset, 32, pool, 0, APR_POLLSET_SELECT); #else status = apr_pollset_create(&pollset, 32, pool, 0); #endif if (status != APR_SUCCESS) return status; /* Don't accept new connection while processing client connection. At least for present time.*/ if (servctx->client_sock) { apr_pollfd_t pfd = { 0 }; pfd.desc_type = APR_POLL_SOCKET; pfd.desc.s = servctx->client_sock; pfd.reqevents = APR_POLLIN | APR_POLLOUT; status = apr_pollset_add(pollset, &pfd); if (status != APR_SUCCESS) goto cleanup; if (servctx->proxy_client_sock) { apr_pollfd_t pfd = { 0 }; pfd.desc_type = APR_POLL_SOCKET; pfd.desc.s = servctx->proxy_client_sock; pfd.reqevents = APR_POLLIN | APR_POLLOUT; status = apr_pollset_add(pollset, &pfd); if (status != APR_SUCCESS) goto cleanup; } } else { apr_pollfd_t pfd = { 0 }; pfd.desc_type = APR_POLL_SOCKET; pfd.desc.s = servctx->serv_sock; pfd.reqevents = APR_POLLIN; status = apr_pollset_add(pollset, &pfd); if (status != APR_SUCCESS) goto cleanup; } status = apr_pollset_poll(pollset, APR_USEC_PER_SEC >> 1, &num, &desc); if (status != APR_SUCCESS) goto cleanup; while (num--) { if (desc->desc.s == servctx->serv_sock) { status = apr_socket_accept(&servctx->client_sock, servctx->serv_sock, servctx->pool); if (status != APR_SUCCESS) goto cleanup; serf__log_skt(TEST_VERBOSE, __FILE__, servctx->client_sock, "server/proxy accepted incoming connection.\n"); apr_socket_opt_set(servctx->client_sock, APR_SO_NONBLOCK, 1); apr_socket_timeout_set(servctx->client_sock, 0); status = APR_SUCCESS; goto cleanup; } if (desc->desc.s == servctx->client_sock) { if (servctx->handshake) { status = servctx->handshake(servctx); if (status) goto cleanup; } /* Replay data to socket. */ status = replay(servctx, desc->rtnevents, pool); if (APR_STATUS_IS_EOF(status)) { apr_socket_close(servctx->client_sock); servctx->client_sock = NULL; if (servctx->reset) servctx->reset(servctx); /* If this is a proxy and the client closed the connection, also close the connection to the server. */ if (servctx->proxy_client_sock) { apr_socket_close(servctx->proxy_client_sock); servctx->proxy_client_sock = NULL; goto cleanup; } } else if (APR_STATUS_IS_EAGAIN(status)) { status = APR_SUCCESS; } else if (status != APR_SUCCESS) { /* Real error. */ goto cleanup; } } if (desc->desc.s == servctx->proxy_client_sock) { /* Replay data to proxy socket. */ status = proxy_replay(servctx, desc->rtnevents, pool); if (APR_STATUS_IS_EOF(status)) { apr_socket_close(servctx->proxy_client_sock); servctx->proxy_client_sock = NULL; } else if (APR_STATUS_IS_EAGAIN(status)) { status = APR_SUCCESS; } else if (status != APR_SUCCESS) { /* Real error. */ goto cleanup; } } desc++; } cleanup: apr_pollset_destroy(pollset); return status; }
static void justsleep(abts_case *tc, void *data) { apr_int32_t nsds; const apr_pollfd_t *hot_files; apr_pollset_t *pollset; apr_status_t rv; apr_time_t t1, t2; int i; apr_pollset_method_e methods[] = { APR_POLLSET_DEFAULT, APR_POLLSET_SELECT, APR_POLLSET_KQUEUE, APR_POLLSET_PORT, APR_POLLSET_EPOLL, APR_POLLSET_POLL}; nsds = 1; t1 = apr_time_now(); rv = apr_poll(NULL, 0, &nsds, apr_time_from_msec(200)); t2 = apr_time_now(); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); ABTS_INT_EQUAL(tc, 0, nsds); ABTS_ASSERT(tc, "apr_poll() didn't sleep", (t2 - t1) > apr_time_from_msec(100)); for (i = 0; i < sizeof methods / sizeof methods[0]; i++) { rv = apr_pollset_create_ex(&pollset, 5, p, 0, methods[i]); if (rv != APR_ENOTIMPL) { ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); nsds = 1; t1 = apr_time_now(); rv = apr_pollset_poll(pollset, apr_time_from_msec(200), &nsds, &hot_files); t2 = apr_time_now(); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); ABTS_INT_EQUAL(tc, 0, nsds); ABTS_ASSERT(tc, "apr_pollset_poll() didn't sleep", (t2 - t1) > apr_time_from_msec(100)); rv = apr_pollset_destroy(pollset); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } rv = apr_pollcb_create_ex(&pollcb, 5, p, 0, methods[0]); if (rv != APR_ENOTIMPL) { ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); t1 = apr_time_now(); rv = apr_pollcb_poll(pollcb, apr_time_from_msec(200), NULL, NULL); t2 = apr_time_now(); ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv)); ABTS_ASSERT(tc, "apr_pollcb_poll() didn't sleep", (t2 - t1) > apr_time_from_msec(100)); /* no apr_pollcb_destroy() */ } } }
static void pollset_remove(abts_case *tc, void *data) { apr_status_t rv; apr_pollset_t *pollset; const apr_pollfd_t *hot_files; apr_pollfd_t pfd; apr_int32_t num; rv = apr_pollset_create_ex(&pollset, 5, p, 0, default_pollset_impl); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); pfd.p = p; pfd.desc_type = APR_POLL_SOCKET; pfd.reqevents = APR_POLLOUT; pfd.desc.s = s[0]; pfd.client_data = (void *)1; rv = apr_pollset_add(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); pfd.desc.s = s[1]; pfd.client_data = (void *)2; rv = apr_pollset_add(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); pfd.desc.s = s[2]; pfd.client_data = (void *)3; rv = apr_pollset_add(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); pfd.desc.s = s[3]; pfd.client_data = (void *)4; rv = apr_pollset_add(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_pollset_poll(pollset, 1000, &num, &hot_files); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, 4, num); /* now remove the pollset element referring to desc s[1] */ pfd.desc.s = s[1]; pfd.client_data = (void *)999; /* not used on this call */ rv = apr_pollset_remove(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* this time only three should match */ rv = apr_pollset_poll(pollset, 1000, &num, &hot_files); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, 3, num); ABTS_PTR_EQUAL(tc, (void *)1, hot_files[0].client_data); ABTS_PTR_EQUAL(tc, s[0], hot_files[0].desc.s); ABTS_PTR_EQUAL(tc, (void *)3, hot_files[1].client_data); ABTS_PTR_EQUAL(tc, s[2], hot_files[1].desc.s); ABTS_PTR_EQUAL(tc, (void *)4, hot_files[2].client_data); ABTS_PTR_EQUAL(tc, s[3], hot_files[2].desc.s); /* now remove the pollset elements referring to desc s[2] */ pfd.desc.s = s[2]; pfd.client_data = (void *)999; /* not used on this call */ rv = apr_pollset_remove(pollset, &pfd); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* this time only two should match */ rv = apr_pollset_poll(pollset, 1000, &num, &hot_files); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_INT_EQUAL(tc, 2, num); ABTS_ASSERT(tc, "Incorrect socket in result set", ((hot_files[0].desc.s == s[0]) && (hot_files[1].desc.s == s[3])) || ((hot_files[0].desc.s == s[3]) && (hot_files[1].desc.s == s[0]))); ABTS_ASSERT(tc, "Incorrect client data in result set", ((hot_files[0].client_data == (void *)1) && (hot_files[1].client_data == (void *)4)) || ((hot_files[0].client_data == (void *)4) && (hot_files[1].client_data == (void *)1))); }