Skip to content

Commit 809d398

Browse files
committed
Fix in async Recv and other updates
1 parent 03f9475 commit 809d398

File tree

4 files changed

+67
-24
lines changed

4 files changed

+67
-24
lines changed

contrib/win32/prototypes/WinsockClient/sock-app.cpp

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ char recvbuf[DEFAULT_BUFLEN];
2020
char sendbuf[DEFAULT_BUFLEN];
2121
bool keep_going = true;
2222
__int64 rec_bytes = 0, sent_bytes = 0;
23-
bool server = true;
23+
enum _mode {
24+
server,
25+
client,
26+
child
27+
};
28+
enum _mode mode = server;
29+
bool rec_live = true, send_live = true;
2430

2531

2632
void prep_send_buf()
@@ -40,6 +46,7 @@ DWORD WINAPI RecvThread(
4046
rec = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
4147
rec_bytes += rec;
4248
}
49+
rec_live = false;
4350
return 0;
4451
}
4552

@@ -52,6 +59,7 @@ DWORD WINAPI SendThread(
5259
rec = send(ConnectSocket, sendbuf + rnd, DEFAULT_BUFLEN - rnd, 0);
5360
sent_bytes += rec;
5461
}
62+
send_live = false;
5563
return 0;
5664
}
5765

@@ -64,7 +72,7 @@ int __cdecl main(int argc, char **argv)
6472
hints;
6573

6674
int iResult;
67-
75+
6876

6977
// Validate the parameters
7078
if ((argc < 2) || (strlen(argv[1]) > 1)) {
@@ -73,7 +81,9 @@ int __cdecl main(int argc, char **argv)
7381
}
7482

7583
if (argv[1][0] == 'c')
76-
server = false;
84+
mode = client;
85+
else if (argv[1][0] == 'o')
86+
mode = child;
7787

7888
// Initialize Winsock
7989
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -87,15 +97,19 @@ int __cdecl main(int argc, char **argv)
8797
hints.ai_socktype = SOCK_STREAM;
8898
hints.ai_protocol = IPPROTO_TCP;
8999

100+
prep_send_buf();
101+
90102
// Resolve the server address and port
91-
iResult = getaddrinfo(argv[2], argv[3], &hints, &result);
92-
if (iResult != 0) {
93-
printf("getaddrinfo failed with error: %d\n", iResult);
94-
WSACleanup();
95-
return 1;
103+
if (mode != child) {
104+
iResult = getaddrinfo(argv[2], argv[3], &hints, &result);
105+
if (iResult != 0) {
106+
printf("getaddrinfo failed with error: %d\n", iResult);
107+
WSACleanup();
108+
return 1;
109+
}
96110
}
97111

98-
if (!server) {
112+
if (mode == client) {
99113
// Attempt to connect to an address until one succeeds
100114
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
101115

@@ -124,7 +138,11 @@ int __cdecl main(int argc, char **argv)
124138
return 1;
125139
}
126140
}
141+
else if (mode == child) {
142+
ConnectSocket = atoi(argv[2]);
143+
}
127144
else {
145+
128146
SOCKET ListenSocket;
129147
// Create a SOCKET for connecting to server
130148
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
@@ -154,17 +172,34 @@ int __cdecl main(int argc, char **argv)
154172
}
155173

156174
// Accept a client socket
157-
ConnectSocket = accept(ListenSocket, NULL, NULL);
158-
if (ConnectSocket == INVALID_SOCKET) {
159-
printf("accept failed with error: %d\n", WSAGetLastError());
160-
closesocket(ListenSocket);
161-
WSACleanup();
162-
return 1;
175+
while (1) {
176+
ConnectSocket = accept(ListenSocket, NULL, NULL);
177+
if (ConnectSocket == INVALID_SOCKET) {
178+
printf("accept failed with error: %d\n", WSAGetLastError());
179+
closesocket(ListenSocket);
180+
WSACleanup();
181+
return 1;
182+
}
183+
if (!SetHandleInformation((HANDLE)ConnectSocket, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
184+
printf("unable to set inheritance on socket handle: %p\n", ConnectSocket);
185+
int sock_int = ConnectSocket & 0xffffffff;
186+
char cmd[MAX_PATH];
187+
STARTUPINFOA si;
188+
PROCESS_INFORMATION pi;
189+
ZeroMemory(&si, sizeof(si)); ZeroMemory(&pi, sizeof(pi));
190+
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
191+
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
192+
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
193+
sprintf(cmd, "%s o %d", argv[0], sock_int);
194+
//spawn a child
195+
if (!CreateProcessA(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
196+
printf("child creation failed: %d\n", GetLastError());
197+
closesocket(ConnectSocket);
163198
}
164-
// No longer need server socket
165-
closesocket(ListenSocket);
166199

167200

201+
// No longer need server socket
202+
closesocket(ListenSocket);
168203
}
169204

170205
freeaddrinfo(result);
@@ -201,23 +236,25 @@ int __cdecl main(int argc, char **argv)
201236
return 1;
202237
}
203238

204-
printf("\t Recv(Kb/s) \t\t Sent(Kb/s)\n");
239+
printf("\t %-20s %-20s \n", "Recv(Kbps)", "Send(Kbps)");
205240
__int64 last_recv = 0;
206241
__int64 last_send = 0;
207-
while (1) {
242+
while (rec_live || send_live) {
208243
if (WAIT_OBJECT_0 != WaitForSingleObject(timer, INFINITE)) {
209244
printf("wait failed %d\n", GetLastError());
210245
break;
211246
}
212247
__int64 now_recv = rec_bytes;
213248
__int64 now_send = sent_bytes;
214249

215-
printf("\r\t %lld \t\t %lld", (now_recv - last_recv) / 2048, (now_send - last_send) / 2048);
250+
printf("\r\t %-20lld %-20lld", (now_recv - last_recv) / (2*1048), (now_send - last_send) / (2*1048));
216251
last_recv = now_recv;
217252
last_send = now_send;
218253

219254
}
220255

256+
printf("\n\n");
257+
221258
closesocket(ConnectSocket);
222259
WSACleanup();
223260

contrib/win32/win32compat/fileio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ VOID CALLBACK ReadCompletionRoutine(
299299
}
300300

301301
/* initiate an async read */
302+
/* TODO: make this a void func, store error in context */
302303
int
303304
fileio_ReadFileEx(struct w32_io* pio) {
304305
debug2("ReadFileEx io:%p", pio);

contrib/win32/win32compat/socketio.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct acceptEx_context {
9292
};
9393

9494
/* initiate async acceptEx*/
95+
/* TODO - always return 0, set error in context, accept() will pick it up*/
9596
int
9697
socketio_acceptEx(struct w32_io* pio) {
9798
struct acceptEx_context *context;
@@ -207,6 +208,7 @@ CALLBACK WSARecvCompletionRoutine(
207208
}
208209

209210
/* initiates async receive operation*/
211+
/* TODO - always return 0, or make this a void func. any error should be put in context*/
210212
int
211213
socketio_WSARecv(struct w32_io* pio, BOOL* completed) {
212214
int ret = 0;
@@ -255,9 +257,10 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed) {
255257
pio->read_details.pending = TRUE;
256258
}
257259
else {
258-
errno = errno_from_WSALastError();
259-
debug("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno);
260-
return -1;
260+
/* io has completed due to error, recv() will pick it up */
261+
debug("WSARecv - WSARecv() ERROR:%d io:%p", WSAGetLastError(), pio);
262+
pio->read_details.error = WSAGetLastError();
263+
return 0;
261264
}
262265
}
263266

@@ -407,8 +410,8 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) {
407410
}
408411
else {
409412
errno = errno_from_WSAError(pio->read_details.error);
410-
pio->read_details.error = 0;
411413
debug("recv - from CB ERROR:%d, io:%p", pio->read_details.error, pio);
414+
pio->read_details.error = 0;
412415
return -1;
413416
}
414417
}

contrib/win32/win32compat/termio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static DWORD WINAPI ReadThread(
4646
return 0;
4747
}
4848

49+
/* TODO - make this a void func*/
4950
int
5051
termio_initiate_read(struct w32_io* pio) {
5152
HANDLE read_thread;
@@ -73,6 +74,7 @@ termio_initiate_read(struct w32_io* pio) {
7374
return 0;
7475
}
7576

77+
/* TODO - make this a void func*/
7678
static VOID CALLBACK WriteAPCProc(
7779
_In_ ULONG_PTR dwParam
7880
) {

0 commit comments

Comments
 (0)