Exemple #1
0
struct hfp_gw *hfp_gw_new(int fd)
{
	struct hfp_gw *hfp;

	if (fd < 0)
		return NULL;

	hfp = new0(struct hfp_gw, 1);
	if (!hfp)
		return NULL;

	hfp->fd = fd;
	hfp->close_on_unref = false;

	hfp->read_buf = ringbuf_new(4096);
	if (!hfp->read_buf) {
		free(hfp);
		return NULL;
	}

	hfp->write_buf = ringbuf_new(4096);
	if (!hfp->write_buf) {
		ringbuf_free(hfp->read_buf);
		free(hfp);
		return NULL;
	}

	hfp->io = io_new(fd);
	if (!hfp->io) {
		ringbuf_free(hfp->write_buf);
		ringbuf_free(hfp->read_buf);
		free(hfp);
		return NULL;
	}

	hfp->cmd_handlers = queue_new();
	if (!hfp->cmd_handlers) {
		io_destroy(hfp->io);
		ringbuf_free(hfp->write_buf);
		ringbuf_free(hfp->read_buf);
		free(hfp);
		return NULL;
	}

	if (!io_set_read_handler(hfp->io, can_read_data, hfp,
							read_watch_destroy)) {
		queue_destroy(hfp->cmd_handlers, destroy_cmd_handler);
		io_destroy(hfp->io);
		ringbuf_free(hfp->write_buf);
		ringbuf_free(hfp->read_buf);
		free(hfp);
		return NULL;
	}

	hfp->writer_active = false;
	hfp->result_pending = false;

	return hfp_gw_ref(hfp);
}
static struct bt_hci *create_hci(int fd)
{
	struct bt_hci *hci;

	if (fd < 0)
		return NULL;

	hci = new0(struct bt_hci, 1);
	if (!hci)
		return NULL;

	hci->io = io_new(fd);
	if (!hci->io) {
		free(hci);
		return NULL;
	}

	hci->is_stream = true;
	hci->writer_active = false;
	hci->num_cmds = 1;
	hci->next_cmd_id = 1;
	hci->next_evt_id = 1;

	hci->cmd_queue = queue_new();
	if (!hci->cmd_queue) {
		io_destroy(hci->io);
		free(hci);
		return NULL;
	}

	hci->rsp_queue = queue_new();
	if (!hci->rsp_queue) {
		queue_destroy(hci->cmd_queue, NULL);
		io_destroy(hci->io);
		free(hci);
		return NULL;
	}

	hci->evt_list = queue_new();
	if (!hci->evt_list) {
		queue_destroy(hci->rsp_queue, NULL);
		queue_destroy(hci->cmd_queue, NULL);
		io_destroy(hci->io);
		free(hci);
		return NULL;
	}

	if (!io_set_read_handler(hci->io, io_read_callback, hci, NULL)) {
		queue_destroy(hci->evt_list, NULL);
		queue_destroy(hci->rsp_queue, NULL);
		queue_destroy(hci->cmd_queue, NULL);
		io_destroy(hci->io);
		free(hci);
		return NULL;
	}

	return bt_hci_ref(hci);
}
Exemple #3
0
static void mscd_destroy(MSCD* mscd)
{
    int i;
    for (i = 0; i < mscd->lun_count; ++i)
    {
        if (MSCD_SCSI(mscd)[i] != NULL)
            scsis_destroy(MSCD_SCSI(mscd)[i]);
    }
    io_destroy(mscd->data);
    io_destroy(mscd->control);
    free(mscd);
}
Exemple #4
0
void cdc_acmd_destroy(CDC_ACMD* cdc_acmd)
{
    io_destroy(cdc_acmd->notify);

    io_destroy(cdc_acmd->rx);
    stream_close(cdc_acmd->rx_stream_handle);
    stream_destroy(cdc_acmd->rx_stream);

    io_destroy(cdc_acmd->tx);
    stream_close(cdc_acmd->tx_stream_handle);
    stream_destroy(cdc_acmd->tx_stream);

    free(cdc_acmd);
}
int main(int ac, char **av) {
	int afd, fd;
	aio_context_t ctx = 0;
	char const *testfn = "/tmp/eventfd-aio-test.data";

	fprintf(stdout, "creating an eventfd ...\n");
	if ((afd = eventfd(0)) == -1) {
		perror("eventfd");
		return 2;
	}
	fprintf(stdout, "done! eventfd = %d\n", afd);
	if (io_setup(TESTFILE_SIZE / IORTX_SIZE + 256, &ctx)) {
		perror("io_setup");
		return 3;
	}
	if ((fd = open(testfn, O_RDWR | O_CREAT, 0644)) == -1) {
		perror(testfn);
		return 4;
	}
	ftruncate(fd, TESTFILE_SIZE);

	fcntl(afd, F_SETFL, fcntl(afd, F_GETFL, 0) | O_NONBLOCK);

	test_write(ctx, fd, TESTFILE_SIZE, afd);
	test_read(ctx, fd, TESTFILE_SIZE, afd);

	io_destroy(ctx);
	close(fd);
	close(afd);
	remove(testfn);

	return 0;
}
Exemple #6
0
static void IOManager_dealloc(IOManager *self) {
   io_destroy(self->ctx);
   PyMem_Free(self->events);
   PyMem_Free(self->cbs);
   close(self->fd);
   Py_TYPE(self)->tp_free(self);
}
Exemple #7
0
static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx)
{
    afalg_ctx *actx;

    if (ctx == NULL) {
        ALG_WARN("NULL parameter passed to function %s\n", __func__);
        return 0;
    }

    actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
    if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) {
        ALG_WARN("%s afalg ctx passed\n",
                 ctx == NULL ? "NULL" : "Uninitialised");
        return 0;
    }

    close(actx->sfd);
    close(actx->bfd);
# ifdef ALG_ZERO_COPY
    close(actx->zc_pipe[0]);
    close(actx->zc_pipe[1]);
# endif
    /* close efd in sync mode, async mode is closed in afalg_waitfd_cleanup() */
    if (actx->aio.mode == MODE_SYNC)
        close(actx->aio.efd);
    io_destroy(actx->aio.aio_ctx);

    return 1;
}
Exemple #8
0
int main(){
	int i;
	pthread_t reaperThread;
	/* memory alignment is very essential for memory writes*/
	posix_memalign((void**)&buffer,BUFFERSIZE,BUFFERSIZE);
	filedes=open(PATH,O_RDONLY|O_DIRECT,0644);	/* Open the file for reading */
	if(filedes<0){
		printf("Error Opening File\n");
		return 0; 
	}
	io_setup(MAXEVENTS,&context);				/* Initialize context */
    /* Create a separate thread to process results */
	pthread_create(&reaperThread,NULL,Reap,(void *)&i);

	for(i=0;i<100;i++){
		SubmitRead(i);					/* Submit Requests for Reading */
	}	

	pthread_join(reaperThread,NULL);	/* Wait till reaperThread Exits */

	/* Deallocate file descriptor and the context */

	close(filedes);
	io_destroy(context);
	return 0;
}
Exemple #9
0
static bool disconnect_cb(struct io *io, void *user_data)
{
	struct bt_att *att = user_data;
	int err;
	socklen_t len;

	len = sizeof(err);

	if (getsockopt(att->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
		util_debug(att->debug_callback, att->debug_data,
					"Failed to obtain disconnect error: %s",
					strerror(errno));
		err = 0;
	}

	util_debug(att->debug_callback, att->debug_data,
					"Physical link disconnected: %s",
					strerror(err));

	io_destroy(att->io);
	att->io = NULL;

	bt_att_cancel_all(att);

	bt_att_ref(att);

	queue_foreach(att->disconn_list, disconn_handler, INT_TO_PTR(err));

	bt_att_unregister_all(att);
	bt_att_unref(att);

	return false;
}
Exemple #10
0
int o2test_aio_destroy(struct o2test_aio *o2a)
{
	int ret = 0, i;

	ret = io_destroy(o2a->o2a_ctx);
	if (ret) {
		ret = errno;
		fprintf(stderr, "error %s during %s\n", strerror(errno),
			"io_destroy");
		ret = -1;
	}

	for (i = 0; i < o2a->o2a_nr_events; i++)
		if (o2a->o2a_iocbs[i])
			free(o2a->o2a_iocbs[i]);

	if (o2a->o2a_iocbs)
		free(o2a->o2a_iocbs);

	o2a->o2a_ctx = NULL;
	o2a->o2a_nr_events = 0;
	o2a->o2a_cr_event = 0;

	return ret;
}
static void
ngx_epoll_done(ngx_cycle_t *cycle)
{
    if (close(ep) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "epoll close() failed");
    }

    ep = -1;

#if (NGX_HAVE_FILE_AIO)

    if (io_destroy(ngx_aio_ctx) != 0) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "io_destroy() failed");
    }

    ngx_aio_ctx = 0;

#endif

    ngx_free(event_list);

    event_list = NULL;
    nevents = 0;
}
Exemple #12
0
static void bt_att_free(struct bt_att *att)
{
	if (att->pending_req)
		destroy_att_send_op(att->pending_req);

	if (att->pending_ind)
		destroy_att_send_op(att->pending_ind);

	io_destroy(att->io);
	bt_crypto_unref(att->crypto);

	queue_destroy(att->req_queue, NULL);
	queue_destroy(att->ind_queue, NULL);
	queue_destroy(att->write_queue, NULL);
	queue_destroy(att->notify_list, NULL);
	queue_destroy(att->disconn_list, NULL);

	if (att->timeout_destroy)
		att->timeout_destroy(att->timeout_data);

	if (att->debug_destroy)
		att->debug_destroy(att->debug_data);

	free(att->local_sign);
	free(att->remote_sign);

	free(att->buf);

	free(att);
}
Exemple #13
0
void h2_mplx_request_done(h2_mplx **pm, int stream_id, const h2_request **preq)
{
    h2_mplx *m = *pm;
    int acquired;
    
    if (enter_mutex(m, &acquired) == APR_SUCCESS) {
        h2_io *io = h2_io_set_get(m->stream_ios, stream_id);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, m->c,
                      "h2_mplx(%ld): request(%d) done", m->id, stream_id);
        if (io) {
            io->worker_done = 1;
            if (io->orphaned) {
                io_destroy(m, io, 0);
                if (m->join_wait) {
                    apr_thread_cond_signal(m->join_wait);
                }
            }
            else {
                /* hang around until the stream deregisteres */
            }
        }
        
        if (preq) {
            /* someone wants another request, if we have */
            *preq = pop_request(m);
        }
        if (!preq || !*preq) {
            /* No request to hand back to the worker, NULLify reference
             * and decrement count */
            *pm = NULL;
        }
        leave_mutex(m, acquired);
    }
}
Exemple #14
0
void client_destroy(Client *client) {
    bool destroy_pending_requests = false;
    PendingRequest *pending_request;

    if (client->pending_request_count > 0) {
        log_warn("Destroying client ("CLIENT_SIGNATURE_FORMAT") while %d request(s) are still pending",
                 client_expand_signature(client), client->pending_request_count);

        if (network_create_zombie(client) < 0) {
            log_error("Could not create zombie for %d pending request(s) of ("CLIENT_SIGNATURE_FORMAT")",
                      client->pending_request_count, client_expand_signature(client));

            destroy_pending_requests = true;
        }
    }

    writer_destroy(&client->response_writer);

    event_remove_source(client->io->handle, EVENT_SOURCE_TYPE_GENERIC);
    io_destroy(client->io);
    free(client->io);

    if (destroy_pending_requests) {
        while (client->pending_request_sentinel.next != &client->pending_request_sentinel) {
            pending_request = containerof(client->pending_request_sentinel.next, PendingRequest, client_node);

            pending_request_remove_and_free(pending_request);
        }
    }

    if (client->destroy_done != NULL) {
        client->destroy_done();
    }
}
Exemple #15
0
static PyObject *IOManager_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
   static char *kwlist[] = {"nr_events", NULL};
   unsigned nr_events;
   IOManager *rv;
   
   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "I", kwlist,
      &nr_events)) return NULL;
   
   if (!(rv = (IOManager*)type->tp_alloc(type, 0))) return NULL;
   
   if ((rv->fd = eventfd(0,0)) < 0) {
      PyErr_SetFromErrno(PyExc_OSError);
      Py_DECREF(rv);
      return NULL;
   }
   if (fcntl(rv->fd, F_SETFL, O_NONBLOCK)) {
      PyErr_SetFromErrno(PyExc_OSError);
      Py_DECREF(rv);
      return NULL;
   };
   
   memset(&rv->ctx, 0, sizeof(io_context_t));
   if (io_setup(nr_events, &rv->ctx)) {
      PyErr_SetFromErrno(PyExc_OSError);
      close(rv->fd);
      Py_DECREF(rv);
      return NULL;
   };
   
   if (!(rv->events = PyMem_Malloc(sizeof(struct io_event)*nr_events))) {
      close(rv->fd);
      io_destroy(rv->ctx);
      Py_DECREF(rv);
      return NULL;
   }
   if (!(rv->cbs = PyMem_Malloc(sizeof(struct iocb*)*nr_events))) {
      close(rv->fd);
      PyMem_Free(rv->events);
      io_destroy(rv->ctx);
      Py_DECREF(rv);
      return NULL;
   }
   
   rv->nr_events = nr_events;
   rv->pending_events = 0;
   return (void*)rv;
}
Exemple #16
0
static void
blockdev_aio_destroy_cb(void *io_device, void *ctx_buf)
{
	struct blockdev_aio_io_channel *io_channel = ctx_buf;

	io_destroy(io_channel->io_ctx);
	free(io_channel->events);
	spdk_poller_unregister(&io_channel->poller, NULL);
}
Exemple #17
0
void vfss_resize_buf(VFSS_TYPE* vfss, unsigned int size)
{
    if (size > vfss->io_size)
    {
        io_destroy(vfss->io);
        vfss->io = io_create(size + sizeof(STORAGE_STACK));
        vfss->io_size = size;
    }
}
int libcheck_init (struct checker * c)
{
	unsigned long pgsize = getpagesize();
	struct directio_context * ct;
	long flags;

	ct = malloc(sizeof(struct directio_context));
	if (!ct)
		return 1;
	memset(ct, 0, sizeof(struct directio_context));

	if (io_setup(1, &ct->ioctx) != 0) {
		condlog(1, "io_setup failed");
		free(ct);
		return 1;
	}

	if (ioctl(c->fd, BLKBSZGET, &ct->blksize) < 0) {
		MSG(c, "cannot get blocksize, set default");
		ct->blksize = 512;
	}
	if (ct->blksize > 4096) {
		/*
		 * Sanity check for DASD; BSZGET is broken
		 */
		ct->blksize = 4096;
	}
	if (!ct->blksize)
		goto out;
	ct->buf = (unsigned char *)malloc(ct->blksize + pgsize);
	if (!ct->buf)
		goto out;

	flags = fcntl(c->fd, F_GETFL);
	if (flags < 0)
		goto out;
	if (!(flags & O_DIRECT)) {
		flags |= O_DIRECT;
		if (fcntl(c->fd, F_SETFL, flags) < 0)
			goto out;
		ct->reset_flags = 1;
	}

	ct->ptr = (unsigned char *) (((unsigned long)ct->buf + pgsize - 1) &
		  (~(pgsize - 1)));

	/* Sucessfully initialized, return the context. */
	c->context = (void *) ct;
	return 0;

out:
	if (ct->buf)
		free(ct->buf);
	io_destroy(ct->ioctx);
	free(ct);
	return 1;
}
Exemple #19
0
int main(int argc, char **argv)
{
	int lc;			/* loop counter */
	char *msg;		/* parse_opts() return message */

	io_context_t ctx = -1;
	long expected_return;

	if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		Tst_count = 0;

/*
DESCRIPTION
       io_destroy  removes  the asynchronous I/O context from the list of I/O
       contexts and then destroys it.  io_destroy can also  cancel  any  out-
       standing asynchronous I/O actions on ctx and block on completion.

RETURN VALUE
       io_destroy returns 0 on success.

ERRORS
       EINVAL The AIO context specified by ctx is invalid.
*/
		expected_return = -EINVAL;
		TEST(io_destroy(ctx));

		if (TEST_RETURN == 0) {
			tst_resm(TFAIL, "call succeeded unexpectedly");
		} else if (TEST_RETURN == expected_return) {
			tst_resm(TPASS, "expected failure - "
				 "returned value = %ld : %s", TEST_RETURN,
				 strerror(-1 * TEST_RETURN));
		} else {
			tst_resm(TFAIL, "unexpected returned value - %ld - "
				 "expected %ld", TEST_RETURN, expected_return);
		}

		/*
		   EFAULT The context pointed to is invalid.
		 */

		/*
		   ENOSYS io_destroy is not implemented on this architecture.
		 */
		/* Crackerjack has a test case for ENOSYS. But Testing for ENOSYS
		   is not meaningful for LTP, I think.
		   -- Masatake */
	}
	cleanup();

	tst_exit();
}
Exemple #20
0
h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
{
    apr_status_t status;
    h2_stream *stream = NULL;
    AP_DEBUG_ASSERT(m);
    if (m->aborted) {
        return NULL;
    }
    status = apr_thread_mutex_lock(m->lock);
    if (APR_SUCCESS == status) {
        h2_io *io = h2_io_set_pop_highest_prio(m->ready_ios);
        if (io) {
            stream = h2_stream_set_get(streams, io->id);
            if (stream) {
                if (io->rst_error) {
                    h2_stream_rst(stream, io->rst_error);
                }
                else {
                    AP_DEBUG_ASSERT(io->response);
                    H2_MPLX_IO_OUT(APLOG_TRACE2, m, io, "h2_mplx_next_submit_pre");
                    h2_stream_set_response(stream, io->response, io->bbout);
                    H2_MPLX_IO_OUT(APLOG_TRACE2, m, io, "h2_mplx_next_submit_post");
                }
                
            }
            else {
                /* We have the io ready, but the stream has gone away, maybe
                 * reset by the client. Should no longer happen since such
                 * streams should clear io's from the ready queue.
                 */
                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, m->c, APLOGNO(02953) 
                              "h2_mplx(%ld): stream for response %d closed, "
                              "resetting io to close request processing",
                              m->id, io->id);
                io->orphaned = 1;
                if (io->task_done) {
                    io_destroy(m, io, 1);
                }
                else {
                    /* hang around until the h2_task is done, but
                     * shutdown input and send out any events (e.g. window
                     * updates) asap. */
                    h2_io_in_shutdown(io);
                    h2_io_rst(io, H2_ERR_STREAM_CLOSED);
                    io_process_events(m, io);
                }
            }
            
            if (io->output_drained) {
                apr_thread_cond_signal(io->output_drained);
            }
        }
        apr_thread_mutex_unlock(m->lock);
    }
    return stream;
}
Exemple #21
0
static void uhid_free(struct bt_uhid *uhid)
{
	if (uhid->io)
		io_destroy(uhid->io);

	if (uhid->notify_list)
		queue_destroy(uhid->notify_list, free);

	free(uhid);
}
Exemple #22
0
void FlatFileReader::Close(void)
{

	if (m_fd != -1) close(m_fd);

	io_destroy(m_aio_context);

	m_fd = -1;
	m_aio_context = 0;
}
Exemple #23
0
void rndis_set_vendor_description(HANDLE usbd, unsigned int iface, const char* vendor)
{
    IO* io;
    unsigned int size = strlen(vendor) + 1;
    io = io_create(size);
    strcpy(io_data(io), vendor);
    io->data_size = size;
    io_write_sync(usbd, HAL_IO_REQ(HAL_USBD_IFACE, RNDIS_SET_VENDOR_DESCRIPTION), iface, io);
    io_destroy(io);
}
Exemple #24
0
void aio_termination(void)
{
    int rtn;

    rtn = io_destroy(context);
    if(rtn<0){
	PRINT("Error on io_destory:%s, line:%d\n", __func__, __LINE__);
	exit(1);
    }
}
int main(int argc, char **argv)
{
	pthread_t thread_read; 
	pthread_t thread_write;
	int i;
	int ret;

	if (argc != 2)
		fail("only arg should be file name\n");

	for (i = 0; i < BUFSIZE; ++i)
		buf[i] = 'A' + (char)(i % ('Z'-'A'+1));

	buf[BUFSIZE-1] = '\n';

	handle = open(argv[1], O_CREAT | O_TRUNC | O_DIRECT | O_RDWR, 0600); 
	if (handle == -1) 
		fail("failed to open test file %s, errno: %d\n",
			argv[1], errno);

	memset(&ctxp, 0, sizeof(ctxp));
	ret = io_setup(MAX_AIO_EVENTS, &ctxp);
	if (ret)
		fail("io_setup returned %d\n", ret);

	for (i = 0; i < MAX_AIO_EVENTS; ++i) {

		iocbs[i] = calloc(1, sizeof(struct iocb));
		if (iocbs[i] == NULL)
			fail("failed to allocate an iocb\n");
	
/*		iocbs[i]->data = i; */
		iocbs[i]->aio_fildes = handle;
		iocbs[i]->aio_lio_opcode = IO_CMD_PWRITE;
		iocbs[i]->aio_reqprio = 0;
		iocbs[i]->u.c.buf = buf;
		iocbs[i]->u.c.nbytes = BUFSIZE;
		iocbs[i]->u.c.offset = BUFSIZE*i;
	}

	pthread_create(&thread_read, NULL, (void*)&fun_read, NULL);
	pthread_create(&thread_write, NULL, (void*)&fun_writeN, NULL);

	pthread_join(thread_read, NULL);
	pthread_join(thread_write, NULL);

	io_destroy(ctxp);
	close(handle);

	printf("%u iterations of racing extensions and collection passed\n",
		MAX_AIO_EVENTS);

	return 0;
}
Exemple #26
0
void laio_cleanup(void *s_)
{
    struct qemu_laio_state *s = s_;

    event_notifier_cleanup(&s->e);

    if (io_destroy(s->ctx) != 0) {
        fprintf(stderr, "%s: destroy AIO context %p failed\n",
                        __func__, &s->ctx);
    }
    g_free(s);
}
Exemple #27
0
struct bt_att *bt_att_new(int fd)
{
	struct bt_att *att;

	if (fd < 0)
		return NULL;

	att = new0(struct bt_att, 1);
	if (!att)
		return NULL;

	att->fd = fd;

	att->mtu = ATT_DEFAULT_LE_MTU;
	att->buf = malloc(att->mtu);
	if (!att->buf)
		goto fail;

	att->io = io_new(fd);
	if (!att->io)
		goto fail;

	att->req_queue = queue_new();
	if (!att->req_queue)
		goto fail;

	att->ind_queue = queue_new();
	if (!att->ind_queue)
		goto fail;

	att->write_queue = queue_new();
	if (!att->write_queue)
		goto fail;

	att->notify_list = queue_new();
	if (!att->notify_list)
		goto fail;

	if (!io_set_read_handler(att->io, can_read_data, att, NULL))
		goto fail;

	return bt_att_ref(att);

fail:
	queue_destroy(att->req_queue, NULL);
	queue_destroy(att->ind_queue, NULL);
	queue_destroy(att->write_queue, NULL);
	io_destroy(att->io);
	free(att->buf);
	free(att);

	return NULL;
}
Exemple #28
0
static void
cleanup_ns_worker_ctx(void)
{
	if (g_ns->type == ENTRY_TYPE_AIO_FILE) {
#ifdef HAVE_LIBAIO
		io_destroy(g_ns->u.aio.ctx);
		free(g_ns->u.aio.events);
#endif
	} else {
		spdk_nvme_ctrlr_free_io_qpair(g_ns->u.nvme.qpair);
	}
}
Exemple #29
0
h2_stream *h2_mplx_next_submit(h2_mplx *m, h2_stream_set *streams)
{
    apr_status_t status;
    h2_stream *stream = NULL;
    int acquired;

    AP_DEBUG_ASSERT(m);
    if ((status = enter_mutex(m, &acquired)) == APR_SUCCESS) {
        h2_io *io = h2_io_set_pop_highest_prio(m->ready_ios);
        if (io && !m->aborted) {
            stream = h2_stream_set_get(streams, io->id);
            if (stream) {
                if (io->rst_error) {
                    h2_stream_rst(stream, io->rst_error);
                }
                else {
                    AP_DEBUG_ASSERT(io->response);
                    H2_MPLX_IO_OUT(APLOG_TRACE2, m, io, "h2_mplx_next_submit_pre");
                    h2_stream_set_response(stream, io->response, io->bbout);
                    H2_MPLX_IO_OUT(APLOG_TRACE2, m, io, "h2_mplx_next_submit_post");
                }
            }
            else {
                /* We have the io ready, but the stream has gone away, maybe
                 * reset by the client. Should no longer happen since such
                 * streams should clear io's from the ready queue.
                 */
                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, m->c,  
                              "h2_mplx(%ld): stream for response %d closed, "
                              "resetting io to close request processing",
                              m->id, io->id);
                h2_io_make_orphaned(io, H2_ERR_STREAM_CLOSED);
                if (!io->worker_started || io->worker_done) {
                    io_destroy(m, io, 1);
                }
                else {
                    /* hang around until the h2_task is done, but
                     * shutdown input and send out any events (e.g. window
                     * updates) asap. */
                    h2_io_in_shutdown(io);
                    io_process_events(m, io);
                }
            }
            
            h2_io_signal(io, H2_IO_WRITE);
        }
        leave_mutex(m, acquired);
    }
    return stream;
}
Exemple #30
0
void
mb_aiom_destroy (mb_aiom_t *aiom)
{
    aiom_cb_t *aiom_cb;

    free(aiom->pending);
    free(aiom->events);
    io_destroy(aiom->context);
    while((aiom_cb = mb_res_pool_pop(aiom->cbpool)) != NULL) {
        free(aiom_cb);
    }
    mb_res_pool_destroy(aiom->cbpool);
    free(aiom);
}