Dan Hipschman wrote:
@@ -94,7 +95,8 @@ struct connection_ops { RpcConnection *(*alloc)(void); RPC_STATUS (*open_connection_client)(RpcConnection *conn); RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn); - int (*read)(RpcConnection *conn, void *buffer, unsigned int len); + int (*read)(RpcConnection *conn, void *buffer, unsigned int len, BOOL check_stop_event); + int (*signal_to_stop)(RpcConnection *conn); int (*write)(RpcConnection *conn, const void *buffer, unsigned int len); int (*close)(RpcConnection *conn); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint);
Hmm, I'm not sure it needs to be this complicated.
HeapFree(GetProcessHeap(), 0, msg); }
-static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) -{ - RpcPacket *pkt = the_arg; - RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg); - HeapFree(GetProcessHeap(), 0, pkt); - return 0; -} - static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) { RpcConnection* conn = (RpcConnection*)the_arg; @@ -319,10 +322,14 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) RpcBinding *pbind; RPC_MESSAGE *msg; RPC_STATUS status; - RpcPacket *packet;
TRACE("(%p)\n", conn);
+ EnterCriticalSection(&client_connections_cs); + list_add_head(&client_connections, &conn->client_entry); + ResetEvent(clients_completed_event); + LeaveCriticalSection(&client_connections_cs); + for (;;) { msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE));
@@ -338,17 +345,17 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) break; }
-#if 0 RPCRT4_process_packet(conn, hdr, msg); -#else - packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket)); - packet->conn = conn; - packet->hdr = hdr; - packet->msg = msg; - QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION); -#endif - msg = NULL; } + + EnterCriticalSection(&client_connections_cs); + list_remove(&conn->client_entry); + if (list_empty(&client_connections)) { + TRACE("last in the list to complete (%p)\n", conn); + SetEvent(clients_completed_event); + } + LeaveCriticalSection(&client_connections_cs); + RPCRT4_DestroyConnection(conn); return 0; }
I'm not sure your reasoning for doing this. If I'm not mistaken, this change makes it so that only one RPC call at a time is processed. -- Rob Shearman