Changeset 19562 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- May 10, 2009 9:44:16 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 47117
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
r19370 r19562 45 45 #include "internal/fileaio.h" 46 46 47 #if defined(RT_OS_DARWIN) 48 # include <sys/types.h> 49 # include <sys/sysctl.h> /* for sysctlbyname */ 50 #endif 47 51 #include <aio.h> 48 52 #include <errno.h> … … 70 74 /** Next element in the chain. */ 71 75 struct RTFILEAIOREQINTERNAL *pNext; 76 /** Previous element in the chain. */ 77 struct RTFILEAIOREQINTERNAL *pPrev; 78 /** Current state the request is in. */ 79 RTFILEAIOREQSTATE enmState; 72 80 /** Flag whether this is a flush request. */ 73 81 bool fFlush; … … 183 191 pReqHead = pReqHead->pNext; 184 192 185 /* Clear pointer to next element just for safety. */193 /* Clear pointer to next and previous element just for safety. */ 186 194 pCtxInt->apReqs[pCtxInt->iFirstFree]->pNext = NULL; 195 pCtxInt->apReqs[pCtxInt->iFirstFree]->pPrev = NULL; 187 196 pCtxInt->iFirstFree++; 188 197 Assert(pCtxInt->iFirstFree <= pCtxInt->cMaxRequests); … … 210 219 } 211 220 221 RTR3DECL(int) RTFileAioGetLimits(PRTFILEAIOLIMITS pAioLimits) 222 { 223 int rcBSD = 0; 224 AssertPtrReturn(pAioLimits, VERR_INVALID_POINTER); 225 226 #if defined(RT_OS_DARWIN) 227 int cReqsOutstandingMax = 0; 228 size_t cbParameter = sizeof(int); 229 230 rcBSD = sysctlbyname("kern.aioprocmax", /* name */ 231 &cReqsOutstandingMax, /* Where to store the old value. */ 232 &cbParameter, /* Size of the memory pointed to. */ 233 NULL, /* Where the new value is located. */ 234 NULL); /* Where the size of the new value is stored. */ 235 if (rcBSD == -1) 236 return RTErrConvertFromErrno(errno); 237 238 pAioLimits->cReqsOutstandingMax = cReqsOutstandingMax; 239 pAioLimits->cbBufferAlignment = 0; 240 #else 241 pAioLimits->cReqsOutstandingMax = RTFILEAIO_UNLIMITED_REQS; 242 pAioLimits->cbBufferAlignment = 0; 243 #endif 244 245 return VINF_SUCCESS; 246 } 247 212 248 RTR3DECL(int) RTFileAioReqCreate(PRTFILEAIOREQ phReq) 213 249 { … … 220 256 pReqInt->pCtxInt = NULL; 221 257 pReqInt->u32Magic = RTFILEAIOREQ_MAGIC; 258 RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); 222 259 223 260 *phReq = (RTFILEAIOREQ)pReqInt; … … 227 264 228 265 229 RTDECL( void) RTFileAioReqDestroy(RTFILEAIOREQ hReq)266 RTDECL(int) RTFileAioReqDestroy(RTFILEAIOREQ hReq) 230 267 { 231 268 /* … … 233 270 */ 234 271 if (hReq == NIL_RTFILEAIOREQ) 235 return ;272 return VINF_SUCCESS; 236 273 PRTFILEAIOREQINTERNAL pReqInt = hReq; 237 RTFILEAIOREQ_VALID_RETURN_VOID(pReqInt); 274 RTFILEAIOREQ_VALID_RETURN(pReqInt); 275 RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS); 238 276 239 277 /* … … 242 280 ASMAtomicUoWriteU32(&pReqInt->u32Magic, ~RTFILEAIOREQ_MAGIC); 243 281 RTMemFree(pReqInt); 282 return VINF_SUCCESS; 244 283 } 245 284 … … 257 296 PRTFILEAIOREQINTERNAL pReqInt = hReq; 258 297 RTFILEAIOREQ_VALID_RETURN(pReqInt); 298 RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS); 259 299 Assert(hFile != NIL_RTFILE); 260 300 AssertPtr(pvBuf); … … 271 311 pReqInt->pCtxInt = NULL; 272 312 pReqInt->Rc = VERR_FILE_AIO_IN_PROGRESS; 313 RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED); 273 314 274 315 return VINF_SUCCESS; … … 297 338 298 339 RTFILEAIOREQ_VALID_RETURN(pReqInt); 340 RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS); 299 341 Assert(hFile != NIL_RTFILE); 300 342 … … 302 344 pReqInt->AioCB.aio_fildes = (int)hFile; 303 345 pReqInt->pvUser = pvUser; 346 RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED); 304 347 305 348 return VINF_SUCCESS; … … 320 363 PRTFILEAIOREQINTERNAL pReqInt = hReq; 321 364 RTFILEAIOREQ_VALID_RETURN(pReqInt); 365 RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED); 322 366 323 367 ASMAtomicXchgBool(&pReqInt->fCanceled, true); … … 343 387 344 388 ASMAtomicWritePtr((void* volatile*)&pCtxInt->pReqToCancel, NULL); 389 pReqInt->Rc = VERR_FILE_AIO_CANCELED; 390 RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); 345 391 return VINF_SUCCESS; 346 392 } … … 358 404 PRTFILEAIOREQINTERNAL pReqInt = hReq; 359 405 RTFILEAIOREQ_VALID_RETURN(pReqInt); 406 RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS); 407 RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, PREPARED, VERR_FILE_AIO_NOT_SUBMITTED); 360 408 AssertPtrNull(pcbTransfered); 361 409 362 if ( ( pReqInt->Rc != VERR_FILE_AIO_IN_PROGRESS)410 if ( (RT_SUCCESS(pReqInt->Rc)) 363 411 && (pcbTransfered)) 364 412 *pcbTransfered = pReqInt->cbTransfered; … … 425 473 } 426 474 427 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs , size_t *pcReqs)475 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs) 428 476 { 429 477 int rc = VINF_SUCCESS; … … 452 500 { 453 501 pReqInt = pahReqs[i]; 454 RTFILEAIOREQ_VALID_RETURN(pReqInt); 502 if (RTFILEAIOREQ_IS_NOT_VALID(pReqInt)) 503 { 504 /* Undo everything and stop submitting. */ 505 for (size_t iUndo = 0; iUndo < i; iUndo++) 506 { 507 pReqInt = pahReqs[iUndo]; 508 RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED); 509 pReqInt->pCtxInt = NULL; 510 511 /* Unlink from the list again. */ 512 PRTFILEAIOREQINTERNAL pNext, pPrev; 513 pNext = pReqInt->pNext; 514 pPrev = pReqInt->pPrev; 515 if (pNext) 516 pNext->pPrev = pPrev; 517 if (pPrev) 518 pPrev->pNext = pNext; 519 else 520 pHead = pNext; 521 } 522 rc = VERR_INVALID_HANDLE; 523 break; 524 } 455 525 456 526 pReqInt->pCtxInt = pCtxInt; … … 458 528 /* Link them together. */ 459 529 pReqInt->pNext = pHead; 530 if (pHead) 531 pHead->pPrev = pReqInt; 532 pReqInt->pPrev = NULL; 460 533 pHead = pReqInt; 534 RTFILEAIOREQ_SET_STATE(pReqInt, SUBMITTED); 461 535 462 536 if (pReqInt->fFlush) … … 472 546 if (RT_UNLIKELY(rcPosix < 0)) 473 547 { 474 rc = RTErrConvertFromErrno(errno); 548 if (rcPosix == EAGAIN) 549 rc = VERR_FILE_AIO_INSUFFICIENT_RESSOURCES; 550 else 551 rc = RTErrConvertFromErrno(errno); 552 553 /* Check which ones were not submitted. */ 554 for (i = 0; i < cReqs; i++) 555 { 556 pReqInt = pahReqs[i]; 557 rcPosix = aio_error(&pReqInt->AioCB); 558 if (rcPosix != EINPROGRESS) 559 { 560 if (rcPosix == EINVAL) 561 { 562 /* Was not submitted. */ 563 RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED); 564 } 565 else 566 { 567 /* An error occured. */ 568 RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); 569 pReqInt->Rc = RTErrConvertFromErrno(rcPosix); 570 pReqInt->cbTransfered = 0; 571 } 572 /* Unlink from the list. */ 573 PRTFILEAIOREQINTERNAL pNext, pPrev; 574 pNext = pReqInt->pNext; 575 pPrev = pReqInt->pPrev; 576 if (pNext) 577 pNext->pPrev = pPrev; 578 if (pPrev) 579 pPrev->pNext = pNext; 580 else 581 pHead = pNext; 582 } 583 } 584 475 585 break; 476 586 } … … 479 589 cReqs -= cReqsSubmit; 480 590 pahReqs += cReqsSubmit; 481 *pcReqs += cReqsSubmit;482 591 } 483 592 … … 488 597 RTFILEAIOREQ_VALID_RETURN(pReqInt); 489 598 490 if (pReqInt->fFlush) 599 Assert(pReqInt->fFlush); 600 601 /* 602 * lio_listio does not work with flush requests so 603 * we have to use aio_fsync directly. 604 */ 605 rcPosix = aio_fsync(O_SYNC, &pReqInt->AioCB); 606 if (RT_UNLIKELY(rcPosix < 0)) 491 607 { 492 /* 493 * lio_listio does not work with flush requests so 494 * we have to use aio_fsync directly. 495 */ 496 rcPosix = aio_fsync(O_SYNC, &pReqInt->AioCB); 497 if (RT_UNLIKELY(rcPosix < 0)) 498 { 499 rc = RTErrConvertFromErrno(errno); 500 break; 501 } 502 503 ASMAtomicIncS32(&pCtxInt->cRequests); 504 cReqs--; 505 pahReqs++; 506 *pcReqs++; 608 rc = RTErrConvertFromErrno(errno); 609 RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED); 610 pReqInt->Rc = rc; 611 pReqInt->cbTransfered = 0; 612 613 /* Unlink from the list. */ 614 PRTFILEAIOREQINTERNAL pNext, pPrev; 615 pNext = pReqInt->pNext; 616 pPrev = pReqInt->pPrev; 617 if (pNext) 618 pNext->pPrev = pPrev; 619 if (pPrev) 620 pPrev->pNext = pNext; 621 else 622 pHead = pNext; 623 break; 507 624 } 625 626 ASMAtomicIncS32(&pCtxInt->cRequests); 627 cReqs--; 628 pahReqs++; 508 629 } 509 630 } while (cReqs); … … 625 746 pReq->Rc = RTErrConvertFromErrno(rcReq); 626 747 748 /* Mark the request as finished. */ 749 RTFILEAIOREQ_SET_STATE(pReq, COMPLETED); 627 750 cDone++; 628 751
Note:
See TracChangeset
for help on using the changeset viewer.