virtual bool destroy() { widget_attached_t detached = 0; if ((detached = this->detach())) { return destroy_detached(detached); } return false; }
virtual bool destroy() { attached_t detached = 0; if ((detached = this->detach())) { if ((destroy_detached(detached))) { return true; } } return false; }
virtual bool destroy() { XDisplay* display = 0; XContext detached = None; if (None != (detached = this->detach(display))) { if ((display)) { if ((destroy_detached(*display, detached))) { return true; } } } return false; }
static void destroy_attached(struct pool_entry_t *entry) { h2o_linklist_unlink(&entry->link); destroy_detached(entry); }
void h2o_socketpool_connect(h2o_socketpool_connect_request_t **_req, h2o_socketpool_t *pool, h2o_loop_t *loop, h2o_multithread_receiver_t *getaddr_receiver, h2o_socketpool_connect_cb cb, void *data) { struct pool_entry_t *entry = NULL; if (_req != NULL) *_req = NULL; /* fetch an entry and return it */ pthread_mutex_lock(&pool->_shared.mutex); destroy_expired(pool); while (1) { if (h2o_linklist_is_empty(&pool->_shared.sockets)) break; entry = H2O_STRUCT_FROM_MEMBER(struct pool_entry_t, link, pool->_shared.sockets.next); h2o_linklist_unlink(&entry->link); pthread_mutex_unlock(&pool->_shared.mutex); /* test if the connection is still alive */ char buf[1]; ssize_t rret = recv(entry->sockinfo.fd, buf, 1, MSG_PEEK); if (rret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { /* yes! return it */ h2o_socket_t *sock = h2o_socket_import(loop, &entry->sockinfo); free(entry); sock->on_close.cb = on_close; sock->on_close.data = pool; cb(sock, NULL, data); return; } /* connection is dead, report, close, and retry */ if (rret <= 0) { static long counter = 0; if (__sync_fetch_and_add(&counter, 1) == 0) fprintf(stderr, "[WARN] detected close by upstream before the expected timeout (see issue #679)\n"); } else { static long counter = 0; if (__sync_fetch_and_add(&counter, 1) == 0) fprintf(stderr, "[WARN] unexpectedly received data to a pooled socket (see issue #679)\n"); } destroy_detached(entry); pthread_mutex_lock(&pool->_shared.mutex); } pthread_mutex_unlock(&pool->_shared.mutex); /* FIXME repsect `capacity` */ __sync_add_and_fetch(&pool->_shared.count, 1); /* prepare request object */ h2o_socketpool_connect_request_t *req = h2o_mem_alloc(sizeof(*req)); *req = (h2o_socketpool_connect_request_t){data, cb, pool, loop}; if (_req != NULL) *_req = req; switch (pool->type) { case H2O_SOCKETPOOL_TYPE_NAMED: /* resolve the name, and connect */ req->getaddr_req = h2o_hostinfo_getaddr(getaddr_receiver, pool->peer.host, pool->peer.named_serv, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, AI_ADDRCONFIG | AI_NUMERICSERV, on_getaddr, req); break; case H2O_SOCKETPOOL_TYPE_SOCKADDR: /* connect (using sockaddr_in) */ start_connect(req, (void *)&pool->peer.sockaddr.bytes, pool->peer.sockaddr.len); break; } }
void h2o_socketpool_connect(h2o_socketpool_connect_request_t **_req, h2o_socketpool_t *pool, h2o_url_t *url, h2o_loop_t *loop, h2o_multithread_receiver_t *getaddr_receiver, h2o_socketpool_connect_cb cb, void *data) { struct pool_entry_t *entry = NULL; struct on_close_data_t *close_data; if (_req != NULL) *_req = NULL; size_t target = SIZE_MAX; h2o_linklist_t *sockets = NULL; /* fetch an entry and return it */ pthread_mutex_lock(&pool->_shared.mutex); destroy_expired(pool); /* TODO lookup outside this critical section */ if (is_global_pool(pool)) { target = lookup_target(pool, url); if (target == SIZE_MAX) { h2o_vector_reserve(NULL, &pool->targets, pool->targets.size + 1); pool->targets.entries[pool->targets.size++] = h2o_socketpool_create_target(url, NULL); target = pool->targets.size - 1; } sockets = &pool->targets.entries[target]->_shared.sockets; } else { sockets = &pool->_shared.sockets; } assert(pool->targets.size != 0); while (!h2o_linklist_is_empty(sockets)) { if (is_global_pool(pool)) { entry = H2O_STRUCT_FROM_MEMBER(struct pool_entry_t, target_link, sockets->next); } else { entry = H2O_STRUCT_FROM_MEMBER(struct pool_entry_t, all_link, sockets->next); } h2o_linklist_unlink(&entry->all_link); h2o_linklist_unlink(&entry->target_link); pthread_mutex_unlock(&pool->_shared.mutex); /* test if the connection is still alive */ char buf[1]; ssize_t rret = recv(entry->sockinfo.fd, buf, 1, MSG_PEEK); if (rret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { /* yes! return it */ size_t entry_target = entry->target; h2o_socket_t *sock = h2o_socket_import(loop, &entry->sockinfo); free(entry); close_data = h2o_mem_alloc(sizeof(*close_data)); close_data->pool = pool; close_data->target = entry_target; sock->on_close.cb = on_close; sock->on_close.data = close_data; cb(sock, NULL, data, &pool->targets.entries[entry_target]->url); return; } /* connection is dead, report, close, and retry */ if (rret <= 0) { static long counter = 0; if (__sync_fetch_and_add(&counter, 1) == 0) fprintf(stderr, "[WARN] detected close by upstream before the expected timeout (see issue #679)\n"); } else { static long counter = 0; if (__sync_fetch_and_add(&counter, 1) == 0) fprintf(stderr, "[WARN] unexpectedly received data to a pooled socket (see issue #679)\n"); } destroy_detached(entry); pthread_mutex_lock(&pool->_shared.mutex); }