- Used different overlapped structures for read and write operations on the server side.

- Check for pending i/o requests.

svn path=/trunk/; revision=14373
This commit is contained in:
Hartmut Birr 2005-03-28 18:47:19 +00:00
parent a48a01798c
commit 7189768d70
5 changed files with 46 additions and 29 deletions

View file

@ -147,11 +147,12 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
HeapFree(GetProcessHeap(), 0, pname);
memset(&Connection->ovl, 0, sizeof(Connection->ovl));
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!ConnectNamedPipe(Connection->conn, &Connection->ovl)) {
Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) {
WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError());
if (GetLastError() == ERROR_PIPE_CONNECTED) {
SetEvent(Connection->ovl.hEvent);
SetEvent(Connection->ovl[0].hEvent);
return RPC_S_OK;
} else if (GetLastError() == ERROR_IO_PENDING) {
return RPC_S_OK;
@ -171,10 +172,11 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
HeapFree(GetProcessHeap(), 0, pname);
memset(&Connection->ovl, 0, sizeof(Connection->ovl));
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!ConnectNamedPipe(Connection->conn, &Connection->ovl)) {
Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) {
if (GetLastError() == ERROR_PIPE_CONNECTED) {
SetEvent(Connection->ovl.hEvent);
SetEvent(Connection->ovl[0].hEvent);
return RPC_S_OK;
} else if (GetLastError() == ERROR_IO_PENDING) {
return RPC_S_OK;
@ -225,7 +227,8 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
/* pipe is connected; change to message-read mode. */
dwMode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(conn, &dwMode, NULL, NULL);
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->conn = conn;
}
/* protseq=ncacn_np: named pipes */
@ -259,7 +262,8 @@ RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection)
/* pipe is connected; change to message-read mode. */
dwMode = PIPE_READMODE_MESSAGE;
SetNamedPipeHandleState(conn, &dwMode, NULL, NULL);
Connection->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
Connection->conn = conn;
} else {
ERR("protseq %s not supported\n", Connection->Protseq);
@ -278,9 +282,13 @@ RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection)
CloseHandle(Connection->conn);
Connection->conn = 0;
}
if (Connection->ovl.hEvent) {
CloseHandle(Connection->ovl.hEvent);
Connection->ovl.hEvent = 0;
if (Connection->ovl[0].hEvent) {
CloseHandle(Connection->ovl[0].hEvent);
Connection->ovl[0].hEvent = 0;
}
if (Connection->ovl[1].hEvent) {
CloseHandle(Connection->ovl[1].hEvent);
Connection->ovl[1].hEvent = 0;
}
return RPC_S_OK;
}
@ -294,7 +302,8 @@ RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* Old
/* because of the way named pipes work, we'll transfer the connected pipe
* to the child, then reopen the server binding to continue listening */
NewConnection->conn = OldConnection->conn;
NewConnection->ovl = OldConnection->ovl;
NewConnection->ovl[0] = OldConnection->ovl[0];
NewConnection->ovl[1] = OldConnection->ovl[1];
OldConnection->conn = 0;
memset(&OldConnection->ovl, 0, sizeof(OldConnection->ovl));
*Connection = NewConnection;

View file

@ -32,7 +32,7 @@ typedef struct _RpcConnection
LPSTR NetworkAddr;
LPSTR Endpoint;
HANDLE conn, thread;
OVERLAPPED ovl;
OVERLAPPED ovl[2];
USHORT MaxTransmissionSize;
/* The active interface bound to server. */
RPC_SYNTAX_IDENTIFIER ActiveInterface;

View file

@ -265,11 +265,12 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
}
/* transmit packet header */
if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl)) {
if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl[1]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("WriteFile failed with error %ld\n", GetLastError());
return GetLastError();
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &count, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
return GetLastError();
}
@ -281,11 +282,12 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header,
}
/* send the fragment data */
if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl)) {
if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl[1]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("WriteFile failed with error %ld\n", GetLastError());
return GetLastError();
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &count, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
return GetLastError();
}
@ -317,12 +319,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
TRACE("(%p, %p, %p)\n", Connection, Header, pMsg);
/* read packet common header */
if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl)) {
if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("ReadFile failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
goto fail;
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
if (GetLastError() != ERROR_MORE_DATA) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
@ -355,12 +358,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
/* read the rest of packet header */
if (!ReadFile(Connection->conn, &(*Header)->common + 1,
hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl)) {
hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl[0]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("ReadFile failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
goto fail;
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
if (GetLastError() != ERROR_MORE_DATA) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
@ -405,12 +409,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
}
if (data_length == 0) dwRead = 0; else {
if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl)) {
if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl[0]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("ReadFile failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
goto fail;
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
if (GetLastError() != ERROR_MORE_DATA) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;
@ -437,12 +442,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
TRACE("next header\n");
/* read the header of next packet */
if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl)) {
if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl[0]) &&
ERROR_IO_PENDING != GetLastError()) {
WARN("ReadFile failed with error %ld\n", GetLastError());
status = GetLastError();
goto fail;
}
if (!GetOverlappedResult(Connection->conn, &Connection->ovl, &dwRead, TRUE)) {
if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) {
if (GetLastError() != ERROR_MORE_DATA) {
WARN("GetOverlappedResult failed with error %ld\n", GetLastError());
status = RPC_S_PROTOCOL_ERROR;

View file

@ -483,7 +483,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
conn = cps->conn;
while (conn) {
RPCRT4_OpenConnection(conn);
if (conn->ovl.hEvent) count++;
if (conn->ovl[0].hEvent) count++;
conn = conn->Next;
}
cps = cps->Next;
@ -500,7 +500,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
while (cps) {
conn = cps->conn;
while (conn) {
if (conn->ovl.hEvent) objs[count++] = conn->ovl.hEvent;
if (conn->ovl[0].hEvent) objs[count++] = conn->ovl[0].hEvent;
conn = conn->Next;
}
cps = cps->Next;
@ -536,7 +536,7 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
while (cps) {
conn = cps->conn;
while (conn) {
if (conn->ovl.hEvent == b_handle) break;
if (conn->ovl[0].hEvent == b_handle) break;
conn = conn->Next;
}
if (conn) break;

View file

@ -84,7 +84,9 @@ HANDLE RPCRT4_RpcssNPConnect(void)
if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
{
ERR("Named pipe unavailable after waiting. Something is probably wrong.\n");
return NULL;
CloseHandle(the_pipe);
the_pipe = NULL;
break;
}
}