void HostProxy_GadgetFS::disconnect() { if (!p_is_connected) {fprintf(stderr,"GadgetFS not connected.\n"); return;} if (p_device_file) { close(p_device_file); p_device_file=0; } int i; for (i=0;i<16;i++) { if (p_epin_async[i]) { aiocb* aio=p_epin_async[i]; if (p_epin_active[i]) {aio_cancel(aio->aio_fildes,aio);} if (aio->aio_fildes) {close(aio->aio_fildes);aio->aio_fildes=0;} if (aio->aio_buf) {free((void*)(aio->aio_buf));aio->aio_buf=NULL;} delete(aio); p_epin_async[i]=NULL; } if (p_epout_async[i]) { aiocb* aio=p_epout_async[i]; aio_cancel(aio->aio_fildes,aio); if (aio->aio_fildes) {close(aio->aio_fildes);aio->aio_fildes=0;} if (aio->aio_buf) {free((void*)(aio->aio_buf));aio->aio_buf=NULL;} delete(aio); p_epout_async[i]=NULL; } } unmount_gadget(); p_is_connected = false; }
int main(void) { char tmpfname[256]; int fd; if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) return PTS_UNSUPPORTED; snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_2_2_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf(TNAME " Error at open(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } unlink(tmpfname); if (aio_cancel(fd, NULL) == -1) { printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); return PTS_FAIL; } close(fd); printf("Test PASSED\n"); return PTS_PASS; }
/*=========================================================================== METHOD: CancelRx (Public Method) DESCRIPTION: Cancel any in-progress receive operation RETURN VALUE: bool ===========================================================================*/ bool cComm::CancelRx() { if (mPort == INVALID_HANDLE_VALUE || mpRxCallback == 0) { return false; } int nReadRC = aio_cancel( mPort, &mReadIO ); mpRxCallback = 0; if (nReadRC == -1 && errno == EBADF) { // aio_cancel is broken if file pointer is bad // wait for completion TRACE( "cComm::CancelRx manual wait %d\n", mPort ); DWORD nTemp; if (mReadCanceled.Wait( INFINITE, nTemp ) == 0) { return true; } // Timeout or some other failure return false; } return (nReadRC == AIO_CANCELED); }
RTDECL(int) RTFileAioReqCancel(RTFILEAIOREQ hReq) { PRTFILEAIOREQINTERNAL pReqInt = hReq; RTFILEAIOREQ_VALID_RETURN(pReqInt); RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED); int rcBSD = aio_cancel(pReqInt->AioCB.aio_fildes, &pReqInt->AioCB); if (rcBSD == AIO_CANCELED) { /* * Decrement request count because the request will never arrive at the * completion port. */ AssertMsg(VALID_PTR(pReqInt->pCtxInt), ("Invalid state. Request was canceled but wasn't submitted\n")); ASMAtomicDecS32(&pReqInt->pCtxInt->cRequests); pReqInt->Rc = VERR_FILE_AIO_CANCELED; RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); return VINF_SUCCESS; } else if (rcBSD == AIO_ALLDONE) return VERR_FILE_AIO_COMPLETED; else if (rcBSD == AIO_NOTCANCELED) return VERR_FILE_AIO_IN_PROGRESS; else return RTErrConvertFromErrno(errno); }
int sunos_cancel_transfer(struct usbi_transfer *itransfer) { sunos_xfer_priv_t *tpriv; sunos_dev_handle_priv_t *hpriv; struct libusb_transfer *transfer; struct aiocb *aiocb; uint8_t ep; int ret; tpriv = usbi_transfer_get_os_priv(itransfer); aiocb = &tpriv->aiocb; transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); hpriv = (sunos_dev_handle_priv_t *)transfer->dev_handle->os_priv; ep = sunos_usb_ep_index(transfer->endpoint); ret = aio_cancel(hpriv->eps[ep].datafd, aiocb); usbi_dbg("aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes, hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)? strerror(0):strerror(errno)); if (ret != AIO_CANCELED) { ret = _errno_to_libusb(errno); } else { /* * we don't need to call usbi_handle_transfer_cancellation(), * because we'll handle everything in sunos_async_callback. */ ret = LIBUSB_SUCCESS; } return (ret); }
static void soo_aio_cancel(struct kaiocb *job) { struct socket *so; struct sockbuf *sb; int opcode; so = job->fd_file->f_data; opcode = job->uaiocb.aio_lio_opcode; if (opcode == LIO_READ) sb = &so->so_rcv; else { MPASS(opcode == LIO_WRITE); sb = &so->so_snd; } SOCKBUF_LOCK(sb); if (!aio_cancel_cleared(job)) TAILQ_REMOVE(&sb->sb_aiojobq, job, list); if (TAILQ_EMPTY(&sb->sb_aiojobq)) sb->sb_flags &= ~SB_AIO; SOCKBUF_UNLOCK(sb); aio_cancel(job); }
IoObject *IoAsyncRequest_cancel(IoAsyncRequest *self, IoObject *locals, IoMessage *m) { /*doc AsyncRequest cancel Cancels the request. Returns nil on error or self otherwise. */ int r = aio_cancel(IOCB(self)->aio_fildes, IOCB(self)); return r == 0 ? self : IONIL(self); }
int eDVBRecordFileThread::AsyncIO::cancel(int fd) { int r = poll(); if (r <= 0) return r; // Either no need to cancel, or error return eDebug("[eDVBRecordFileThread] cancelling"); return aio_cancel(fd, &aio); }
void FlatFileReader::Close(void) { printf("CLOSE\n"); if (m_fd) close(m_fd); //io_destroy(m_aio_context); aio_cancel(m_fd, &m_aio_context); m_fd = 0; //m_aio_context = 0; }
ATF_TC_BODY(aio_socket_two_reads, tc) { struct ioreq { struct aiocb iocb; char buffer[1024]; } ioreq[2]; struct aiocb *iocb; unsigned i; int s[2]; char c; ATF_REQUIRE_KERNEL_MODULE("aio"); #if __FreeBSD_version < 1100101 aft_tc_skip("kernel version %d is too old (%d required)", __FreeBSD_version, 1100101); #endif ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1); /* Queue two read requests. */ memset(&ioreq, 0, sizeof(ioreq)); for (i = 0; i < nitems(ioreq); i++) { ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer); ioreq[i].iocb.aio_fildes = s[0]; ioreq[i].iocb.aio_buf = ioreq[i].buffer; ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0); } /* Send a single byte. This should complete one request. */ c = 0xc3; ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1); ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1); /* Determine which request completed and verify the data was read. */ if (iocb == &ioreq[0].iocb) i = 0; else i = 1; ATF_REQUIRE(ioreq[i].buffer[0] == c); i ^= 1; /* * Try to cancel the other request. On broken systems this * will fail and the process will hang on exit. */ ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS); ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED); close(s[1]); close(s[0]); }
int main() { char tmpfname[256]; #define BUF_SIZE 1024 char buf[BUF_SIZE]; int fd; struct aiocb aiocb; #if _POSIX_ASYNCHRONOUS_IO < 0 printf("_POSIX_ASYNCHRONOUS_IO is not supported\n"); return PTS_UNSUPPORTED; #endif snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_1_1_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf(TNAME " Error at open(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } unlink(tmpfname); memset(buf, 0xaa, BUF_SIZE); memset(&aiocb, 0, sizeof(struct aiocb)); aiocb.aio_fildes = fd; aiocb.aio_buf = buf; aiocb.aio_nbytes = BUF_SIZE; if (aio_write(&aiocb) == -1) { printf(TNAME " Error at aio_write(): %s\n", strerror(errno)); return PTS_FAIL; } while (aio_error(&aiocb) == EINPROGRESS); if (aio_cancel(fd, &aiocb) != AIO_ALLDONE) { printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); return PTS_FAIL; } close(fd); printf ("Test PASSED\n"); return PTS_PASS; }
void aio_check_functions(struct aiocb *ai) { (void)aio_cancel(0, ai); (void)aio_error(ai); #if _POSIX_FSYNC > 0 || _POSIX_SYNCHRONIZED_IO > 0 (void)aio_fsync(0, ai); #endif (void)aio_read(ai); (void)aio_return(ai); (void)aio_suspend((const struct aiocb * const *)1234, 0, (struct timespec *)0); (void)aio_write(ai); (void)lio_listio(0, (struct aiocb * const *)1234, 0, (struct sigevent *)0); }
int main(void) { char tmpfname[256]; #define BUF_SIZE 1024 char buf[BUF_SIZE]; int fd, err; struct aiocb aiocb; if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) return PTS_UNSUPPORTED; snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_2_1_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf(TNAME " Error at open(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } unlink(tmpfname); memset(buf, 0xaa, BUF_SIZE); memset(&aiocb, 0, sizeof(struct aiocb)); aiocb.aio_fildes = fd; aiocb.aio_buf = buf; aiocb.aio_nbytes = BUF_SIZE; if (aio_write(&aiocb) == -1) { printf(TNAME " Error at aio_write(): %s\n", strerror(errno)); return PTS_FAIL; } switch (aio_cancel(fd, NULL)) { case -1: printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); return PTS_FAIL; case AIO_NOTCANCELED: do { struct timespec completion_wait_ts = {0, 10000000}; nanosleep(&completion_wait_ts, NULL); err = aio_error(&aiocb); } while (err == EINPROGRESS); } close(fd); printf("Test PASSED\n"); return PTS_PASS; }
int main() { char tmpfname[256]; #define BUF_SIZE 1024 char buf[BUF_SIZE]; int fd; struct aiocb aiocb; if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) return PTS_UNSUPPORTED; snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_cancel_2_1_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf(TNAME " Error at open(): %s\n", strerror(errno)); return PTS_UNRESOLVED; } unlink(tmpfname); memset(buf, 0xaa, BUF_SIZE); memset(&aiocb, 0, sizeof(struct aiocb)); aiocb.aio_fildes = fd; aiocb.aio_buf = buf; aiocb.aio_nbytes = BUF_SIZE; if (aio_write(&aiocb) == -1) { printf(TNAME " Error at aio_write(): %s\n", strerror(errno)); return PTS_FAIL; } if (aio_cancel(fd, NULL) == -1) { printf(TNAME " Error at aio_cancel(): %s\n", strerror(errno)); return PTS_FAIL; } close(fd); printf ("Test PASSED\n"); return PTS_PASS; }
static int do_write_aio_posix(int fd, uint64_t offset, char *buf, int len, struct task *task) { struct timespec ts; struct aiocb cb; struct aiocb const *p_cb; int rv; memset(&ts, 0, sizeof(struct timespec)); ts.tv_sec = task->io_timeout_seconds; memset(&cb, 0, sizeof(struct aiocb)); p_cb = &cb; cb.aio_fildes = fd; cb.aio_buf = buf; cb.aio_nbytes = len; cb.aio_offset = offset; rv = aio_write(&cb); if (rv < 0) return -1; rv = aio_suspend(&p_cb, 1, &ts); if (!rv) return 0; /* the write timed out, try to cancel it... */ rv = aio_cancel(fd, &cb); if (rv < 0) return -1; if (rv == AIO_ALLDONE) return 0; if (rv == AIO_CANCELED) return -EIO; /* Functions that depend on the timeout might consider * the action failed even if it will complete if that * happened after the alloted time frame */ if (rv == AIO_NOTCANCELED) return -EIO; /* undefined error condition */ return -1; }
void IoAsyncRequest_free(IoAsyncRequest *self) { int fd = IOCB(self)->aio_fildes; if (fd) { aio_cancel(fd, IOCB(self)); } if (IOCB_BUFFER(self)) { free(IOCB_BUFFER(self)); } free(IOCB(self)); }
static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags) { int rc; if (c->read->active == 0 && c->write->active == 0) { return NGX_OK; } if (flags & NGX_CLOSE_EVENT) { return NGX_OK; } rc = aio_cancel(c->fd, NULL); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc); if (rc == AIO_CANCELED) { c->read->active = 0; c->write->active = 0; return NGX_OK; } if (rc == AIO_ALLDONE) { c->read->active = 0; c->write->active = 0; ngx_log_error(NGX_LOG_ALERT, c->log, 0, "aio_cancel() returned AIO_ALLDONE"); return NGX_OK; } if (rc == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "aio_cancel() failed"); return NGX_ERROR; } if (rc == AIO_NOTCANCELED) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, "aio_cancel() returned AIO_NOTCANCELED"); return NGX_ERROR; } return NGX_OK; }
static VALUE rb_aio_cancel(int fd, void *cb) { int ret; TRAP_BEG; ret = aio_cancel( fd, cb ); TRAP_END; if (ret != 0) rb_aio_cancel_error(); switch(ret){ case AIO_CANCELED: return c_aio_canceled; case AIO_NOTCANCELED: return c_aio_notcanceled; case AIO_ALLDONE: return c_aio_alldone; } return Qnil; }
void aioCancel(int fd) { aio_ctrl_t *curr; aio_ctrl_t *prev; aio_ctrl_t *next; AIOCB *done_handler; void *their_data; assert(initialised); aio_counts.cancel++; prev = NULL; curr = used_list; for (curr = used_list;; curr = next) { while (curr != NULL) { if (curr->fd == fd) break; prev = curr; curr = curr->next; } if (curr == NULL) break; aio_cancel(&curr->result); if ((done_handler = curr->done_handler)) { their_data = curr->done_handler_data; curr->done_handler = NULL; curr->done_handler_data = NULL; debug(32, 2) ("this be aioCancel\n"); if (cbdataValid(their_data)) done_handler(fd, their_data, -2, -2); cbdataUnlock(their_data); } next = curr->next; if (prev == NULL) used_list = next; else prev->next = next; memPoolFree(aio_ctrl_pool, curr); } }
int main(void) { if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) return PTS_UNSUPPORTED; if (aio_cancel(-1, NULL) != -1) { printf(TNAME " bad aio_cancel return value()\n"); return PTS_FAIL; } if (errno == 0) { printf(TNAME " bad errno value()\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }
static void a_close(struct aio_ring *ring) { int i; for (i=0;i<ring->num_blocks;i++) { struct aio_block *b = &ring->blocks[i]; if (b->blk != -1 && !b->done) { int ret = aio_cancel(ring->fd, b->cb); if (ret == AIO_NOTCANCELED) { aio_suspend(&b->cb, 1, NULL); } aio_error(b->cb); aio_return(b->cb); } if (b->cb) free(b->cb); if (b->buffer) free(b->buffer); } free(ring); }
static int a_schedule(struct aio_ring *ring, int blk) { struct aio_block *b = &ring->blocks[blk % ring->num_blocks]; if (blk == b->blk) return 0; if (b->buffer == NULL) { b->buffer = malloc(ring->block_size); if (b->buffer == NULL) goto failed; } if (b->cb == NULL) { b->cb = malloc(sizeof(*b->cb)); if (b->cb == NULL) goto failed; } if (b->blk != -1 && !b->done) { int ret = aio_cancel(ring->fd, b->cb); if (ret == AIO_NOTCANCELED) { aio_suspend(&b->cb, 1, NULL); } aio_error(b->cb); aio_return(b->cb); } b->blk = blk; memset(b->cb, 0, sizeof(*b->cb)); b->cb->aio_fildes = ring->fd; b->cb->aio_buf = b->buffer; b->cb->aio_nbytes = ring->block_size; b->cb->aio_offset = blk * (off_t)ring->block_size; if (aio_read(b->cb) != 0) goto failed; b->done = 0; return 0; failed: free(b->buffer); free(b->cb); b->buffer = NULL; b->cb = NULL; b->blk = -1; return -1; }
RTDECL(int) RTFileAioReqCancel(RTFILEAIOREQ hReq) { PRTFILEAIOREQINTERNAL pReqInt = hReq; RTFILEAIOREQ_VALID_RETURN(pReqInt); RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED); ASMAtomicXchgBool(&pReqInt->fCanceled, true); int rcPosix = aio_cancel(pReqInt->AioCB.aio_fildes, &pReqInt->AioCB); if (rcPosix == AIO_CANCELED) { PRTFILEAIOCTXINTERNAL pCtxInt = pReqInt->pCtxInt; /* * Notify the waiting thread that the request was canceled. */ AssertMsg(VALID_PTR(pCtxInt), ("Invalid state. Request was canceled but wasn't submitted\n")); Assert(!pCtxInt->pReqToCancel); ASMAtomicWritePtr(&pCtxInt->pReqToCancel, pReqInt); rtFileAioCtxWakeup(pCtxInt); /* Wait for acknowledge. */ int rc = RTSemEventWait(pCtxInt->SemEventCancel, RT_INDEFINITE_WAIT); AssertRC(rc); ASMAtomicWriteNullPtr(&pCtxInt->pReqToCancel); pReqInt->Rc = VERR_FILE_AIO_CANCELED; RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); return VINF_SUCCESS; } else if (rcPosix == AIO_ALLDONE) return VERR_FILE_AIO_COMPLETED; else if (rcPosix == AIO_NOTCANCELED) return VERR_FILE_AIO_IN_PROGRESS; else return RTErrConvertFromErrno(errno); }
/* * aio_issue_cancel() * cancel an in-progress async I/O request */ static void aio_issue_cancel(const char *name, io_req_t *io_req) { int ret; if (io_req->status != EINPROGRESS) return; ret = aio_cancel(io_req->aiocb.aio_fildes, &io_req->aiocb); switch (ret) { case AIO_CANCELED: case AIO_ALLDONE: break; case AIO_NOTCANCELED: pr_dbg(stderr, "%s: async I/O request %d not cancelled\n", name, io_req->request); break; default: pr_err(stderr, "%s: %d error: %d %s\n", name, io_req->request, errno, strerror(errno)); } }
int AioCancel(int v_fd, long v_timeOut) { int ret = 0; long timeStart = time(NULL); while (1) { ret = aio_cancel(v_fd, NULL); if ((AIO_ALLDONE == ret) || (AIO_CANCELED == ret)) { break; } if ((time(NULL) - timeStart) > v_timeOut) { return -ERR_AIO_CANCEL_TIMEOUT; } sleep(1); } return 0; }
void eDVBRecordStreamThread::flush() { eDebug("[eDVBRecordStreamThread] cancelling aio"); switch (aio_cancel(m_fd_dest, NULL)) { case AIO_CANCELED: eDebug("[eDVBRecordStreamThread] ok"); break; case AIO_NOTCANCELED: eDebug("[eDVBRecordStreamThread] not all cancelled"); break; case AIO_ALLDONE: eDebug("[eDVBRecordStreamThread] all done"); break; case -1: eDebug("[eDVBRecordStreamThread] failed: %m"); break; default: eDebug("[eDVBRecordStreamThread] unexpected return code"); break; } // Call inherited flush to clean up the rest. eDVBRecordFileThread::flush(); }
int eDVBRecordStreamThread::writeData(int len) { len = asyncWrite(len); if (len < 0) return len; // Cancel aio on this buffer before returning, streams should not be held up. So we CANCEL // any request that hasn't finished on the second round. int r = m_current_buffer->cancel(m_fd_dest); switch (r) { //case 0: // that's one of these two: case AIO_CANCELED: case AIO_ALLDONE: break; case AIO_NOTCANCELED: eDebug("[eDVBRecordStreamThread] failed to cancel, killing all waiting IO"); aio_cancel(m_fd_dest, NULL); // Poll all open requests, because they are all in error state now. for (AsyncIOvector::iterator it = m_aio.begin(); it != m_aio.end(); ++it) { it->poll(); } break; case -1: eDebug("[eDVBRecordStreamThread] failed: %m"); return r; } // we want to have a consistent state, so wait for completion, just to be sure r = m_current_buffer->wait(); if (r < 0) { eDebug("[eDVBRecordStreamThread] wait failed: %m"); return -1; } return len; }
int main(int argc, char *argv[]) { struct ioRequest *ioList; struct aiocb *aiocbList; struct sigaction sa; int s, j; int numReqs; /* Total number of queued I/O requests */ int openReqs; /* Number of I/O requests still in progress */ if (argc < 2) { fprintf(stderr, "Usage: %s <pathname> <pathname>...\n", argv[0]); exit(EXIT_FAILURE); } numReqs = argc - 1; /* Allocate our arrays */ ioList = calloc(numReqs, sizeof(struct ioRequest)); if (ioList == NULL) errExit("calloc"); aiocbList = calloc(numReqs, sizeof(struct aiocb)); if (aiocbList == NULL) errExit("calloc"); /* Establish handlers for SIGQUIT and the I/O completion signal */ sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sa.sa_handler = quitHandler; if (sigaction(SIGQUIT, &sa, NULL) == -1) errExit("sigaction"); sa.sa_flags = SA_RESTART | SA_SIGINFO; sa.sa_sigaction = aioSigHandler; if (sigaction(IO_SIGNAL, &sa, NULL) == -1) errExit("sigaction"); /* Open each file specified on the command line, and queue a read request on the resulting file descriptor */ for (j = 0; j < numReqs; j++) { ioList[j].reqNum = j; ioList[j].status = EINPROGRESS; ioList[j].aiocbp = &aiocbList[j]; ioList[j].aiocbp->aio_fildes = open(argv[j + 1], O_RDONLY); if (ioList[j].aiocbp->aio_fildes == -1) errExit("open"); printf("opened %s on descriptor %d\n", argv[j + 1], ioList[j].aiocbp->aio_fildes); ioList[j].aiocbp->aio_buf = malloc(BUF_SIZE); if (ioList[j].aiocbp->aio_buf == NULL) errExit("malloc"); ioList[j].aiocbp->aio_nbytes = BUF_SIZE; ioList[j].aiocbp->aio_reqprio = 0; ioList[j].aiocbp->aio_offset = 0; ioList[j].aiocbp->aio_sigevent.sigev_notify = SIGEV_SIGNAL; ioList[j].aiocbp->aio_sigevent.sigev_signo = IO_SIGNAL; ioList[j].aiocbp->aio_sigevent.sigev_value.sival_ptr = &ioList[j]; s = aio_read(ioList[j].aiocbp); if (s == -1) errExit("aio_read"); } openReqs = numReqs; /* Loop, monitoring status of I/O requests */ while (openReqs > 0) { sleep(3); /* Delay between each monitoring step */ if (gotSIGQUIT) { /* On receipt of SIGQUIT, attempt to cancel each of the outstanding I/O requests, and display status returned from the cancellation requests */ printf("got SIGQUIT; canceling I/O requests: \n"); for (j = 0; j < numReqs; j++) { if (ioList[j].status == EINPROGRESS) { printf(" Request %d on descriptor %d:", j, ioList[j].aiocbp->aio_fildes); s = aio_cancel(ioList[j].aiocbp->aio_fildes, ioList[j].aiocbp); if (s == AIO_CANCELED) printf("I/O canceled\n"); else if (s == AIO_NOTCANCELED) printf("I/O not canceled\n"); else if (s == AIO_ALLDONE) printf("I/O all done\n"); else errMsg("aio_cancel"); } } gotSIGQUIT = 0; } /* Check the status of each I/O request that is still in progress */ printf("aio_error():\n"); for (j = 0; j < numReqs; j++) { if (ioList[j].status == EINPROGRESS) { printf(" for request %d (descriptor %d): ", j, ioList[j].aiocbp->aio_fildes); ioList[j].status = aio_error(ioList[j].aiocbp); switch (ioList[j].status) { case 0: printf("I/O succeeded\n"); break; case EINPROGRESS: printf("In progress\n"); break; case ECANCELED: printf("Canceled\n"); break; default: errMsg("aio_error"); break; } if (ioList[j].status != EINPROGRESS) openReqs--; } } } printf("All I/O requests completed\n"); /* Check status return of all I/O requests */ printf("aio_return():\n"); for (j = 0; j < numReqs; j++) { ssize_t s; s = aio_return(ioList[j].aiocbp); printf(" for request %d (descriptor %d): %zd\n", j, ioList[j].aiocbp->aio_fildes, s); } exit(EXIT_SUCCESS); }
static void soaio_process_job(struct socket *so, struct sockbuf *sb, struct kaiocb *job) { struct ucred *td_savedcred; struct thread *td; struct file *fp; struct uio uio; struct iovec iov; size_t cnt; int error, flags; SOCKBUF_UNLOCK(sb); aio_switch_vmspace(job); td = curthread; fp = job->fd_file; retry: td_savedcred = td->td_ucred; td->td_ucred = job->cred; cnt = job->uaiocb.aio_nbytes; iov.iov_base = (void *)(uintptr_t)job->uaiocb.aio_buf; iov.iov_len = cnt; uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; uio.uio_resid = cnt; uio.uio_segflg = UIO_USERSPACE; uio.uio_td = td; flags = MSG_NBIO; /* TODO: Charge ru_msg* to job. */ if (sb == &so->so_rcv) { uio.uio_rw = UIO_READ; #ifdef MAC error = mac_socket_check_receive(fp->f_cred, so); if (error == 0) #endif error = soreceive(so, NULL, &uio, NULL, NULL, &flags); } else { uio.uio_rw = UIO_WRITE; #ifdef MAC error = mac_socket_check_send(fp->f_cred, so); if (error == 0) #endif error = sosend(so, NULL, &uio, NULL, NULL, flags, td); if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { PROC_LOCK(job->userproc); kern_psignal(job->userproc, SIGPIPE); PROC_UNLOCK(job->userproc); } } cnt -= uio.uio_resid; td->td_ucred = td_savedcred; /* XXX: Not sure if this is needed? */ if (cnt != 0 && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; if (error == EWOULDBLOCK) { /* * A read() or write() on the socket raced with this * request. If the socket is now ready, try again. * If it is not, place this request at the head of the * queue to try again when the socket is ready. */ SOCKBUF_LOCK(sb); empty_results++; if (soaio_ready(so, sb)) { empty_retries++; SOCKBUF_UNLOCK(sb); goto retry; } if (!aio_set_cancel_function(job, soo_aio_cancel)) { MPASS(cnt == 0); SOCKBUF_UNLOCK(sb); aio_cancel(job); SOCKBUF_LOCK(sb); } else { TAILQ_INSERT_HEAD(&sb->sb_aiojobq, job, list); } } else { aio_complete(job, cnt, error); SOCKBUF_LOCK(sb); } }
void * POSIX_Init (void *argument) { int fd[MAX]; struct aiocb *aiocbp[MAX+1]; int status, i, policy = SCHED_FIFO; char filename[BUFSIZE]; struct sched_param param; status = rtems_aio_init (); rtems_test_assert (status == 0); param.sched_priority = 30; status = pthread_setschedparam (pthread_self(), policy, ¶m); rtems_test_assert (status == 0); status = mkdir ("/tmp", S_IRWXU); rtems_test_assert (!status); puts ("\n\n*** POSIX AIO TEST 02 ***"); puts ("Init: Open files"); for (i=0; i<MAX; i++) { sprintf (filename, "/tmp/aio_fildes%d",i); fd[i] = open (filename, O_RDWR|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO); rtems_test_assert ( fd[i] != -1); } puts ("Init: [WQ] aio_write on 1st file"); aiocbp[0] = create_aiocb (fd[0]); status = aio_write (aiocbp[0]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_write on 2nd file"); aiocbp[1] = create_aiocb (fd[1]); status = aio_write (aiocbp[1]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_read on 2nd file add by priority"); aiocbp[2] = create_aiocb (fd[1]); status = aio_read (aiocbp[2]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_write on 3rd file"); aiocbp[3] = create_aiocb (fd[2]); status = aio_write (aiocbp[3]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_write on 4th file"); aiocbp[4] = create_aiocb (fd[3]); status = aio_write (aiocbp[4]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_write on 5th file -- [WQ] full"); aiocbp[5] = create_aiocb (fd[4]); status = aio_write (aiocbp[5]); rtems_test_assert (status != -1); puts ("Init: [IQ] aio_write on 6th file"); aiocbp[6] = create_aiocb (fd[5]); status = aio_write (aiocbp[6]); rtems_test_assert (status != -1); puts ("Init: [IQ] aio_write on 7th file"); aiocbp[7] = create_aiocb (fd[6]); status = aio_write (aiocbp[7]); rtems_test_assert (status != -1); puts ("Init: [IQ] aio_read on 7th file add by priority"); aiocbp[8] = create_aiocb (fd[6]); status = aio_read (aiocbp[8]); rtems_test_assert (status != -1); puts ("Init: [WQ] aio_sync on 1st file add by priority"); aiocbp[9] = create_aiocb (fd[0]); status = aio_fsync (O_SYNC, aiocbp[9]); rtems_test_assert (status != -1); puts ("Init: [NONE] aio_cancel aiocbp=NULL and invalid fildes"); status = aio_cancel (WRONG_FD, NULL); rtems_test_assert (status == -1); puts ("Init: [NONE] aio_cancel aiocbp=NULL valid fildes not in queue"); status = aio_cancel (fd[7], NULL); rtems_test_assert (status == AIO_ALLDONE); puts ("Init: [WQ] aio_cancel aiocbp=NULL fildes=fd[1]"); status = aio_cancel (fd[1], NULL); rtems_test_assert (status == AIO_CANCELED); puts ("Init: [IQ] aio_cancel aiocbp=NULL fildes=fd[6]"); status = aio_cancel (fd[6], NULL); rtems_test_assert (status == AIO_CANCELED); puts ("Init: [NONE] aio_cancel aiocbp->aio_fildes != fildes"); status = aio_cancel (fd[4],aiocbp[4]); rtems_test_assert (status == -1 ); puts ("Init: [NONE] aio_cancel FD on [IQ], aiocb not on chain"); aiocbp[10] = create_aiocb (fd[9]); status = aio_cancel (fd[9], aiocbp[10]); rtems_test_assert (status == -1); puts ("Init: [IQ] aio_cancel 6th file only one request"); status = aio_cancel (fd[5], aiocbp[6]); rtems_test_assert (status == AIO_CANCELED); puts ("Init: [WQ] aio_cancel 1st file only one request"); status = aio_cancel (fd[0], aiocbp[9]); rtems_test_assert (status == AIO_CANCELED); puts ("Init: [NONE] aio_cancel empty [IQ]"); status = aio_cancel (fd[5], aiocbp[6]); rtems_test_assert (status == AIO_ALLDONE); puts ("*** END OF POSIX AIO TEST 02 ***"); for (i = 0; i < MAX; i++) { close (fd[i]); free_aiocb (aiocbp[i]); } free_aiocb (aiocbp[i]); rtems_test_exit (0); return NULL; }