Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
c2feafb9
Commit
c2feafb9
authored
Sep 19, 2011
by
Bernhard Loos
Committed by
Alexandre Julliard
Sep 19, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Switch to non-overlapped named pipe operations and use a thread for the…
rpcrt4: Switch to non-overlapped named pipe operations and use a thread for the async listen operation.
parent
d905ba5a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
41 additions
and
39 deletions
+41
-39
rpc_transport.c
dlls/rpcrt4/rpc_transport.c
+41
-39
No files found.
dlls/rpcrt4/rpc_transport.c
View file @
c2feafb9
...
...
@@ -111,8 +111,7 @@ typedef struct _RpcConnection_np
{
RpcConnection
common
;
HANDLE
pipe
;
OVERLAPPED
read_ovl
;
OVERLAPPED
write_ovl
;
HANDLE
listen_thread
;
BOOL
listening
;
}
RpcConnection_np
;
...
...
@@ -122,25 +121,21 @@ static RpcConnection *rpcrt4_conn_np_alloc(void)
return
&
npc
->
common
;
}
static
RPC_STATUS
rpcrt4_conn_listen_pipe
(
RpcConnection_np
*
npc
)
static
DWORD
CALLBACK
listen_thread
(
void
*
arg
)
{
if
(
npc
->
listening
)
return
RPC_S_OK
;
npc
->
listening
=
TRUE
;
RpcConnection_np
*
npc
=
arg
;
for
(;;)
{
if
(
ConnectNamedPipe
(
npc
->
pipe
,
&
npc
->
read_ovl
))
if
(
ConnectNamedPipe
(
npc
->
pipe
,
NULL
))
return
RPC_S_OK
;
switch
(
GetLastError
())
{
case
ERROR_PIPE_CONNECTED
:
SetEvent
(
npc
->
read_ovl
.
hEvent
);
return
RPC_S_OK
;
case
ERROR_IO_PENDING
:
/* will be completed in rpcrt4_protseq_np_wait_for_new_connection */
return
RPC_S_OK
;
case
ERROR_HANDLES_CLOSED
:
/* connection closed during listen */
return
RPC_S_NO_CONTEXT_AVAILABLE
;
case
ERROR_NO_DATA_DETECTED
:
/* client has disconnected, retry */
DisconnectNamedPipe
(
npc
->
pipe
);
...
...
@@ -153,12 +148,28 @@ static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc)
}
}
static
RPC_STATUS
rpcrt4_conn_listen_pipe
(
RpcConnection_np
*
npc
)
{
if
(
npc
->
listening
)
return
RPC_S_OK
;
npc
->
listening
=
TRUE
;
npc
->
listen_thread
=
CreateThread
(
NULL
,
0
,
listen_thread
,
npc
,
0
,
NULL
);
if
(
!
npc
->
listen_thread
)
{
npc
->
listening
=
FALSE
;
ERR
(
"Couldn't create listen thread (error was %d)
\n
"
,
GetLastError
());
return
RPC_S_OUT_OF_RESOURCES
;
}
return
RPC_S_OK
;
}
static
RPC_STATUS
rpcrt4_conn_create_pipe
(
RpcConnection
*
Connection
,
LPCSTR
pname
)
{
RpcConnection_np
*
npc
=
(
RpcConnection_np
*
)
Connection
;
TRACE
(
"listening on %s
\n
"
,
pname
);
npc
->
pipe
=
CreateNamedPipeA
(
pname
,
PIPE_ACCESS_DUPLEX
|
FILE_FLAG_OVERLAPPED
,
npc
->
pipe
=
CreateNamedPipeA
(
pname
,
PIPE_ACCESS_DUPLEX
,
PIPE_TYPE_MESSAGE
|
PIPE_READMODE_MESSAGE
,
PIPE_UNLIMITED_INSTANCES
,
RPC_MAX_PACKET_SIZE
,
RPC_MAX_PACKET_SIZE
,
5000
,
NULL
);
...
...
@@ -170,9 +181,6 @@ static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pnam
return
RPC_S_CANT_CREATE_ENDPOINT
;
}
npc
->
read_ovl
.
hEvent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
npc
->
write_ovl
.
hEvent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
/* Note: we don't call ConnectNamedPipe here because it must be done in the
* server thread as the thread must be alertable */
return
RPC_S_OK
;
...
...
@@ -231,8 +239,6 @@ static RPC_STATUS rpcrt4_conn_open_pipe(RpcConnection *Connection, LPCSTR pname,
/* pipe is connected; change to message-read mode. */
dwMode
=
PIPE_READMODE_MESSAGE
;
SetNamedPipeHandleState
(
pipe
,
&
dwMode
,
NULL
,
NULL
);
npc
->
read_ovl
.
hEvent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
npc
->
write_ovl
.
hEvent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
NULL
);
npc
->
pipe
=
pipe
;
return
RPC_S_OK
;
...
...
@@ -360,11 +366,9 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np *
* to the child, then reopen the server binding to continue listening */
new_npc
->
pipe
=
old_npc
->
pipe
;
new_npc
->
read_ovl
=
old_npc
->
read_ovl
;
new_npc
->
write_ovl
=
old_npc
->
write_ovl
;
new_npc
->
listen_thread
=
old_npc
->
listen_thread
;
old_npc
->
pipe
=
0
;
memset
(
&
old_npc
->
read_ovl
,
0
,
sizeof
(
old_npc
->
read_ovl
));
memset
(
&
old_npc
->
write_ovl
,
0
,
sizeof
(
old_npc
->
write_ovl
));
old_npc
->
listen_thread
=
0
;
old_npc
->
listening
=
FALSE
;
}
...
...
@@ -413,9 +417,7 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection,
while
(
bytes_left
)
{
DWORD
bytes_read
;
ret
=
ReadFile
(
npc
->
pipe
,
buf
,
bytes_left
,
&
bytes_read
,
&
npc
->
read_ovl
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_IO_PENDING
)
ret
=
GetOverlappedResult
(
npc
->
pipe
,
&
npc
->
read_ovl
,
&
bytes_read
,
TRUE
);
ret
=
ReadFile
(
npc
->
pipe
,
buf
,
bytes_left
,
&
bytes_read
,
NULL
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_MORE_DATA
)
ret
=
TRUE
;
if
(
!
ret
||
!
bytes_read
)
...
...
@@ -437,9 +439,7 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection,
while
(
bytes_left
)
{
DWORD
bytes_written
;
ret
=
WriteFile
(
npc
->
pipe
,
buf
,
bytes_left
,
&
bytes_written
,
&
npc
->
write_ovl
);
if
(
!
ret
&&
GetLastError
()
==
ERROR_IO_PENDING
)
ret
=
GetOverlappedResult
(
npc
->
pipe
,
&
npc
->
write_ovl
,
&
bytes_written
,
TRUE
);
ret
=
WriteFile
(
npc
->
pipe
,
buf
,
bytes_left
,
&
bytes_written
,
NULL
);
if
(
!
ret
||
!
bytes_written
)
break
;
bytes_left
-=
bytes_written
;
...
...
@@ -456,13 +456,9 @@ static int rpcrt4_conn_np_close(RpcConnection *Connection)
CloseHandle
(
npc
->
pipe
);
npc
->
pipe
=
0
;
}
if
(
npc
->
read_ovl
.
hEvent
)
{
CloseHandle
(
npc
->
read_ovl
.
hEvent
);
npc
->
read_ovl
.
hEvent
=
0
;
}
if
(
npc
->
write_ovl
.
hEvent
)
{
CloseHandle
(
npc
->
write_ovl
.
hEvent
);
npc
->
write_ovl
.
hEvent
=
0
;
if
(
npc
->
listen_thread
)
{
CloseHandle
(
npc
->
listen_thread
);
npc
->
listen_thread
=
0
;
}
return
0
;
}
...
...
@@ -666,7 +662,7 @@ static void *rpcrt4_protseq_np_get_wait_array(RpcServerProtseq *protseq, void *p
conn
=
CONTAINING_RECORD
(
protseq
->
conn
,
RpcConnection_np
,
common
);
while
(
conn
)
{
rpcrt4_conn_listen_pipe
(
conn
);
if
(
conn
->
read_ovl
.
hEvent
)
if
(
conn
->
listen_thread
)
(
*
count
)
++
;
conn
=
CONTAINING_RECORD
(
conn
->
common
.
Next
,
RpcConnection_np
,
common
);
}
...
...
@@ -687,7 +683,7 @@ static void *rpcrt4_protseq_np_get_wait_array(RpcServerProtseq *protseq, void *p
*
count
=
1
;
conn
=
CONTAINING_RECORD
(
protseq
->
conn
,
RpcConnection_np
,
common
);
while
(
conn
)
{
if
((
objs
[
*
count
]
=
conn
->
read_ovl
.
hEvent
))
if
((
objs
[
*
count
]
=
conn
->
listen_thread
))
(
*
count
)
++
;
conn
=
CONTAINING_RECORD
(
conn
->
common
.
Next
,
RpcConnection_np
,
common
);
}
...
...
@@ -734,12 +730,18 @@ static int rpcrt4_protseq_np_wait_for_new_connection(RpcServerProtseq *protseq,
EnterCriticalSection
(
&
protseq
->
cs
);
conn
=
CONTAINING_RECORD
(
protseq
->
conn
,
RpcConnection_np
,
common
);
while
(
conn
)
{
if
(
b_handle
==
conn
->
read_ovl
.
hEvent
)
break
;
if
(
b_handle
==
conn
->
listen_thread
)
break
;
conn
=
CONTAINING_RECORD
(
conn
->
common
.
Next
,
RpcConnection_np
,
common
);
}
cconn
=
NULL
;
if
(
conn
)
RPCRT4_SpawnConnection
(
&
cconn
,
&
conn
->
common
);
{
DWORD
exit_code
;
if
(
GetExitCodeThread
(
conn
->
listen_thread
,
&
exit_code
)
&&
exit_code
==
RPC_S_OK
)
RPCRT4_SpawnConnection
(
&
cconn
,
&
conn
->
common
);
CloseHandle
(
conn
->
listen_thread
);
conn
->
listen_thread
=
0
;
}
else
ERR
(
"failed to locate connection for handle %p
\n
"
,
b_handle
);
LeaveCriticalSection
(
&
protseq
->
cs
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment