VirtualBox

source: vbox/trunk/src/VBox/VMM/PDMAsyncCompletionFileFailsafe.cpp@ 22544

Last change on this file since 22544 was 22309, checked in by vboxsync, 15 years ago

PDMAsyncCompletion: Add first part of the cache for file I/O

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/* $Id: PDMAsyncCompletionFileFailsafe.cpp 22309 2009-08-17 20:59:28Z vboxsync $ */
2/** @file
3 * PDM Async I/O - Transport data asynchronous in R3 using EMT.
4 * Failsafe File I/O manager.
5 */
6
7/*
8 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
23#include <iprt/types.h>
24#include <VBox/log.h>
25
26#include "PDMAsyncCompletionFileInternal.h"
27
28static int pdmacFileAioMgrFailsafeProcessEndpoint(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint)
29{
30 int rc = VINF_SUCCESS;
31 PPDMACTASKFILE pTasks = pdmacFileEpGetNewTasks(pEndpoint);
32
33 while (pTasks)
34 {
35 PPDMACTASKFILE pCurr = pTasks;
36
37 switch (pCurr->enmTransferType)
38 {
39 case PDMACTASKFILETRANSFER_FLUSH:
40 {
41 rc = RTFileFlush(pEndpoint->File);
42 break;
43 }
44 case PDMACTASKFILETRANSFER_READ:
45 case PDMACTASKFILETRANSFER_WRITE:
46 {
47 if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_READ)
48 {
49 rc = RTFileReadAt(pEndpoint->File, pCurr->Off,
50 pCurr->DataSeg.pvSeg,
51 pCurr->DataSeg.cbSeg,
52 NULL);
53 }
54 else
55 {
56 rc = RTFileWriteAt(pEndpoint->File, pCurr->Off,
57 pCurr->DataSeg.pvSeg,
58 pCurr->DataSeg.cbSeg,
59 NULL);
60 }
61
62 break;
63 }
64 default:
65 AssertMsgFailed(("Invalid transfer type %d\n", pTasks->enmTransferType));
66 }
67
68 AssertRC(rc);
69
70 pCurr->pfnCompleted(pCurr, pCurr->pvUser);
71 pdmacFileTaskFree(pEndpoint, pCurr);
72
73 pTasks = pTasks->pNext;
74 }
75
76 return rc;
77}
78
79/**
80 * A fallback method in case something goes wrong with the normal
81 * I/O manager.
82 */
83int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser)
84{
85 int rc = VINF_SUCCESS;
86 PPDMACEPFILEMGR pAioMgr = (PPDMACEPFILEMGR)pvUser;
87
88 while ( (pAioMgr->enmState == PDMACEPFILEMGRSTATE_RUNNING)
89 || (pAioMgr->enmState == PDMACEPFILEMGRSTATE_SUSPENDING))
90 {
91 if (!ASMAtomicReadBool(&pAioMgr->fWokenUp))
92 {
93 ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, true);
94 rc = RTSemEventWait(pAioMgr->EventSem, RT_INDEFINITE_WAIT);
95 ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, false);
96 AssertRC(rc);
97 }
98 ASMAtomicXchgBool(&pAioMgr->fWokenUp, false);
99
100 /* Process endpoint events first. */
101 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint = pAioMgr->pEndpointsHead;
102 while (pEndpoint)
103 {
104 rc = pdmacFileAioMgrFailsafeProcessEndpoint(pEndpoint);
105 AssertRC(rc);
106 pEndpoint = pEndpoint->AioMgr.pEndpointNext;
107 }
108
109 /* Now check for an external blocking event. */
110 if (pAioMgr->fBlockingEventPending)
111 {
112 switch (pAioMgr->enmBlockingEvent)
113 {
114 case PDMACEPFILEAIOMGRBLOCKINGEVENT_ADD_ENDPOINT:
115 {
116 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpointNew = pAioMgr->BlockingEventData.AddEndpoint.pEndpoint;
117 AssertMsg(VALID_PTR(pEndpointNew), ("Adding endpoint event without a endpoint to add\n"));
118
119 pEndpointNew->enmState = PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE;
120
121 pEndpointNew->AioMgr.pEndpointNext = pAioMgr->pEndpointsHead;
122 pEndpointNew->AioMgr.pEndpointPrev = NULL;
123 if (pAioMgr->pEndpointsHead)
124 pAioMgr->pEndpointsHead->AioMgr.pEndpointPrev = pEndpointNew;
125 pAioMgr->pEndpointsHead = pEndpointNew;
126 break;
127 }
128 case PDMACEPFILEAIOMGRBLOCKINGEVENT_REMOVE_ENDPOINT:
129 {
130 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpointRemove = pAioMgr->BlockingEventData.RemoveEndpoint.pEndpoint;
131 AssertMsg(VALID_PTR(pEndpointRemove), ("Removing endpoint event without a endpoint to remove\n"));
132
133 pEndpointRemove->enmState = PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING;
134
135 PPDMASYNCCOMPLETIONENDPOINTFILE pPrev = pEndpointRemove->AioMgr.pEndpointPrev;
136 PPDMASYNCCOMPLETIONENDPOINTFILE pNext = pEndpointRemove->AioMgr.pEndpointNext;
137
138 if (pPrev)
139 pPrev->AioMgr.pEndpointNext = pNext;
140 else
141 pAioMgr->pEndpointsHead = pNext;
142
143 if (pNext)
144 pNext->AioMgr.pEndpointPrev = pPrev;
145 break;
146 }
147 case PDMACEPFILEAIOMGRBLOCKINGEVENT_CLOSE_ENDPOINT:
148 {
149 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpointClose = pAioMgr->BlockingEventData.CloseEndpoint.pEndpoint;
150 AssertMsg(VALID_PTR(pEndpointClose), ("Close endpoint event without a endpoint to Close\n"));
151
152 pEndpointClose->enmState = PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING;
153
154 /* Make sure all tasks finished. */
155 rc = pdmacFileAioMgrFailsafeProcessEndpoint(pEndpointClose);
156 AssertRC(rc);
157 }
158 case PDMACEPFILEAIOMGRBLOCKINGEVENT_SHUTDOWN:
159 break;
160 case PDMACEPFILEAIOMGRBLOCKINGEVENT_SUSPEND:
161 break;
162 default:
163 AssertMsgFailed(("Invalid event type %d\n", pAioMgr->enmBlockingEvent));
164 }
165
166 /* Release the waiting thread. */
167 rc = RTSemEventSignal(pAioMgr->EventSemBlock);
168 AssertRC(rc);
169 }
170 }
171
172 return rc;
173}
174
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette