- Fix pipe connection to non-waiting pipes.
- More corrections to the cancellation logic.
- Minor correction to read/write event setting (still I'm getting
infinite loops there in some cases).
Modified: trunk/reactos/drivers/fs/np/create.c
Modified: trunk/reactos/drivers/fs/np/fsctrl.c
Modified: trunk/reactos/drivers/fs/np/rw.c
Modified: trunk/reactos/drivers/fs/np/volume.c
_____
Modified: trunk/reactos/drivers/fs/np/create.c
--- trunk/reactos/drivers/fs/np/create.c 2005-03-06 14:03:37 UTC
(rev 13855)
+++ trunk/reactos/drivers/fs/np/create.c 2005-03-06 16:42:36 UTC
(rev 13856)
@@ -148,39 +148,13 @@
KeUnlockMutex(&DeviceExt->PipeListLock);
/*
- * Step 2. Search for listening server FCB.
- */
-
- /*
* Acquire the lock for FCB lists. From now on no modifications to
the
* FCB lists are allowed, because it can cause various
misconsistencies.
*/
KeLockMutex(&Pipe->FcbListLock);
- if (!SpecialAccess)
- {
- ServerFcb = NpfsFindListeningServerInstance(Pipe);
- if (ServerFcb == NULL)
- {
- /* Not found, bail out with error for FILE_OPEN requests. */
- DPRINT("No listening server fcb found!\n");
- KeUnlockMutex(&Pipe->FcbListLock);
- Irp->IoStatus.Status = STATUS_PIPE_BUSY;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_PIPE_BUSY;
- }
- }
- else if (IsListEmpty(&Pipe->ServerFcbListHead))
- {
- DPRINT("No server fcb found!\n");
- KeUnlockMutex(&Pipe->FcbListLock);
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
- }
-
/*
- * Step 3. Create the client FCB.
+ * Step 2. Create the client FCB.
*/
ClientFcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (ClientFcb == NULL)
@@ -227,6 +201,73 @@
KeInitializeEvent(&ClientFcb->Event, SynchronizationEvent, FALSE);
/*
+ * Step 3. Search for listening server FCB.
+ */
+
+ if (!SpecialAccess)
+ {
+ /*
+ * WARNING: Point of no return! Once we get the server FCB it's
+ * possible that we completed a wait request and so we have to
+ * complete even this request.
+ */
+
+ ServerFcb = NpfsFindListeningServerInstance(Pipe);
+ if (ServerFcb == NULL)
+ {
+ PLIST_ENTRY CurrentEntry;
+ PNPFS_FCB Fcb;
+
+ /*
+ * If no waiting server FCB was found then try to pick
+ * one of the listing server FCB on the pipe.
+ */
+
+ CurrentEntry = Pipe->ServerFcbListHead.Flink;
+ while (CurrentEntry != &Pipe->ServerFcbListHead)
+ {
+ Fcb = CONTAINING_RECORD(CurrentEntry, NPFS_FCB,
FcbListEntry);
+ if (Fcb->PipeState == FILE_PIPE_LISTENING_STATE)
+ {
+ ServerFcb = Fcb;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ /*
+ * No one is listening to me?! I'm so lonely... :(
+ */
+
+ if (ServerFcb == NULL)
+ {
+ /* Not found, bail out with error for FILE_OPEN requests.
*/
+ DPRINT("No listening server fcb found!\n");
+ if (ClientFcb->Data)
+ ExFreePool(ClientFcb->Data);
+ KeUnlockMutex(&Pipe->FcbListLock);
+ Irp->IoStatus.Status = STATUS_PIPE_BUSY;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_PIPE_BUSY;
+ }
+ }
+ else
+ {
+ /* Signal the server thread and remove it from the waiter
list */
+ /* FIXME: Merge this with the NpfsFindListeningServerInstance
routine. */
+ NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
+ }
+ }
+ else if (IsListEmpty(&Pipe->ServerFcbListHead))
+ {
+ DPRINT("No server fcb found!\n");
+ KeUnlockMutex(&Pipe->FcbListLock);
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /*
* Step 4. Add the client FCB to a list and connect it if possible.
*/
@@ -240,9 +281,6 @@
ServerFcb->OtherSide = ClientFcb;
ClientFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
ServerFcb->PipeState = FILE_PIPE_CONNECTED_STATE;
-
- /* Signal the server thread and remove it from the waiter list */
- NpfsSignalAndRemoveListeningServerInstance(Pipe, ServerFcb);
}
KeUnlockMutex(&Pipe->FcbListLock);
_____
Modified: trunk/reactos/drivers/fs/np/fsctrl.c
--- trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 14:03:37 UTC
(rev 13855)
+++ trunk/reactos/drivers/fs/np/fsctrl.c 2005-03-06 16:42:36 UTC
(rev 13856)
@@ -26,19 +26,12 @@
DPRINT1("NpfsListeningCancelRoutine() called\n");
- /* FIXME: Not tested. */
-
IoReleaseCancelSpinLock(Irp->CancelIrql);
Waiter = Irp->Tail.Overlay.DriverContext[0];
KeLockMutex(&Waiter->Pipe->FcbListLock);
RemoveEntryList(&Waiter->Entry);
- if (IoSetCancelRoutine(Waiter->Irp, NULL) == NULL)
- {
- KeUnlockMutex(&Waiter->Pipe->FcbListLock);
- return;
- }
KeUnlockMutex(&Waiter->Pipe->FcbListLock);
Irp->IoStatus.Status = STATUS_CANCELLED;
@@ -53,7 +46,6 @@
PNPFS_FCB Fcb)
{
PNPFS_WAITER_ENTRY Entry;
- KIRQL OldIrql;
Entry = ExAllocatePool(NonPagedPool, sizeof(NPFS_WAITER_ENTRY));
if (Entry == NULL)
@@ -63,21 +55,26 @@
Entry->Fcb = Fcb;
Entry->Pipe = Fcb->Pipe;
- IoAcquireCancelSpinLock(&OldIrql);
+ KeLockMutex(&Fcb->Pipe->FcbListLock);
+
+ IoMarkIrpPending(Irp);
+ Irp->Tail.Overlay.DriverContext[0] = Entry;
+ InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
+
+ IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
+
if (!Irp->Cancel)
{
- Irp->Tail.Overlay.DriverContext[0] = Entry;
- IoMarkIrpPending(Irp);
- IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
- KeLockMutex(&Fcb->Pipe->FcbListLock);
- InsertTailList(&Fcb->Pipe->WaiterListHead, &Entry->Entry);
KeUnlockMutex(&Fcb->Pipe->FcbListLock);
- IoReleaseCancelSpinLock(OldIrql);
return STATUS_PENDING;
}
- /* IRP has already been cancelled */
- IoReleaseCancelSpinLock(OldIrql);
-
+
+ RemoveEntryList(&Entry->Entry);
+
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ KeUnlockMutex(&Fcb->Pipe->FcbListLock);
ExFreePool(Entry);
return STATUS_CANCELLED;
_____
Modified: trunk/reactos/drivers/fs/np/rw.c
--- trunk/reactos/drivers/fs/np/rw.c 2005-03-06 14:03:37 UTC (rev
13855)
+++ trunk/reactos/drivers/fs/np/rw.c 2005-03-06 16:42:36 UTC (rev
13856)
@@ -165,7 +165,10 @@
if (Length == 0)
{
- KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
+ if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+ {
+ KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
+ }
KeResetEvent(&Fcb->Event);
break;
}
@@ -197,6 +200,11 @@
}
else
{
+ KeResetEvent(&Fcb->Event);
+ if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
+ {
+ KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT,
FALSE);
+ }
Fcb->ReadDataAvailable = 0;
Fcb->WriteQuotaAvailable = Fcb->MaxDataLength;
}
@@ -204,11 +212,6 @@
if (Information > 0)
{
- if (Fcb->PipeState == FILE_PIPE_CONNECTED_STATE)
- {
- KeSetEvent(&WriterFcb->Event, IO_NO_INCREMENT, FALSE);
- }
- KeResetEvent(&Fcb->Event);
break;
}
}
@@ -383,12 +386,12 @@
ReaderFcb->WriteQuotaAvailable = 0;
}
- if (Information > 0)
- {
- KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
- KeResetEvent(&Fcb->Event);
- break;
- }
+ if (Information > 0)
+ {
+ KeSetEvent(&ReaderFcb->Event, IO_NO_INCREMENT, FALSE);
+ KeResetEvent(&Fcb->Event);
+ break;
+ }
}
}
_____
Modified: trunk/reactos/drivers/fs/np/volume.c
--- trunk/reactos/drivers/fs/np/volume.c 2005-03-06 14:03:37 UTC
(rev 13855)
+++ trunk/reactos/drivers/fs/np/volume.c 2005-03-06 16:42:36 UTC
(rev 13856)
@@ -36,7 +36,7 @@
DPRINT("NpfsQueryFsDeviceInformation() finished.\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}