Merge branch 'sg/index-format-doc-update' into maint
[git/debian.git] / compat / simple-ipc / ipc-win32.c
blob20ea7b65e0ba6311b22678fba5201e4a7ebeb8ce
1 #include "cache.h"
2 #include "simple-ipc.h"
3 #include "strbuf.h"
4 #include "pkt-line.h"
5 #include "thread-utils.h"
6 #include "accctrl.h"
7 #include "aclapi.h"
9 #ifndef SUPPORTS_SIMPLE_IPC
11 * This source file should only be compiled when Simple IPC is supported.
12 * See the top-level Makefile.
14 #error SUPPORTS_SIMPLE_IPC not defined
15 #endif
17 static int initialize_pipe_name(const char *path, wchar_t *wpath, size_t alloc)
19 int off = 0;
20 struct strbuf realpath = STRBUF_INIT;
22 if (!strbuf_realpath(&realpath, path, 0))
23 return -1;
25 off = swprintf(wpath, alloc, L"\\\\.\\pipe\\");
26 if (xutftowcs(wpath + off, realpath.buf, alloc - off) < 0)
27 return -1;
29 /* Handle drive prefix */
30 if (wpath[off] && wpath[off + 1] == L':') {
31 wpath[off + 1] = L'_';
32 off += 2;
35 for (; wpath[off]; off++)
36 if (wpath[off] == L'/')
37 wpath[off] = L'\\';
39 strbuf_release(&realpath);
40 return 0;
43 static enum ipc_active_state get_active_state(wchar_t *pipe_path)
45 if (WaitNamedPipeW(pipe_path, NMPWAIT_USE_DEFAULT_WAIT))
46 return IPC_STATE__LISTENING;
48 if (GetLastError() == ERROR_SEM_TIMEOUT)
49 return IPC_STATE__NOT_LISTENING;
51 if (GetLastError() == ERROR_FILE_NOT_FOUND)
52 return IPC_STATE__PATH_NOT_FOUND;
54 trace2_data_intmax("ipc-debug", NULL, "getstate/waitpipe/gle",
55 (intmax_t)GetLastError());
57 return IPC_STATE__OTHER_ERROR;
60 enum ipc_active_state ipc_get_active_state(const char *path)
62 wchar_t pipe_path[MAX_PATH];
64 if (initialize_pipe_name(path, pipe_path, ARRAY_SIZE(pipe_path)) < 0)
65 return IPC_STATE__INVALID_PATH;
67 return get_active_state(pipe_path);
70 #define WAIT_STEP_MS (50)
72 static enum ipc_active_state connect_to_server(
73 const wchar_t *wpath,
74 DWORD timeout_ms,
75 const struct ipc_client_connect_options *options,
76 int *pfd)
78 DWORD t_start_ms, t_waited_ms;
79 DWORD step_ms;
80 HANDLE hPipe = INVALID_HANDLE_VALUE;
81 DWORD mode = PIPE_READMODE_BYTE;
82 DWORD gle;
84 *pfd = -1;
86 for (;;) {
87 hPipe = CreateFileW(wpath, GENERIC_READ | GENERIC_WRITE,
88 0, NULL, OPEN_EXISTING, 0, NULL);
89 if (hPipe != INVALID_HANDLE_VALUE)
90 break;
92 gle = GetLastError();
94 switch (gle) {
95 case ERROR_FILE_NOT_FOUND:
96 if (!options->wait_if_not_found)
97 return IPC_STATE__PATH_NOT_FOUND;
98 if (!timeout_ms)
99 return IPC_STATE__PATH_NOT_FOUND;
101 step_ms = (timeout_ms < WAIT_STEP_MS) ?
102 timeout_ms : WAIT_STEP_MS;
103 sleep_millisec(step_ms);
105 timeout_ms -= step_ms;
106 break; /* try again */
108 case ERROR_PIPE_BUSY:
109 if (!options->wait_if_busy)
110 return IPC_STATE__NOT_LISTENING;
111 if (!timeout_ms)
112 return IPC_STATE__NOT_LISTENING;
114 t_start_ms = (DWORD)(getnanotime() / 1000000);
116 if (!WaitNamedPipeW(wpath, timeout_ms)) {
117 DWORD gleWait = GetLastError();
119 if (gleWait == ERROR_SEM_TIMEOUT)
120 return IPC_STATE__NOT_LISTENING;
122 trace2_data_intmax("ipc-debug", NULL,
123 "connect/waitpipe/gle",
124 (intmax_t)gleWait);
126 return IPC_STATE__OTHER_ERROR;
130 * A pipe server instance became available.
131 * Race other client processes to connect to
132 * it.
134 * But first decrement our overall timeout so
135 * that we don't starve if we keep losing the
136 * race. But also guard against special
137 * NPMWAIT_ values (0 and -1).
139 t_waited_ms = (DWORD)(getnanotime() / 1000000) - t_start_ms;
140 if (t_waited_ms < timeout_ms)
141 timeout_ms -= t_waited_ms;
142 else
143 timeout_ms = 1;
144 break; /* try again */
146 default:
147 trace2_data_intmax("ipc-debug", NULL,
148 "connect/createfile/gle",
149 (intmax_t)gle);
151 return IPC_STATE__OTHER_ERROR;
155 if (!SetNamedPipeHandleState(hPipe, &mode, NULL, NULL)) {
156 gle = GetLastError();
157 trace2_data_intmax("ipc-debug", NULL,
158 "connect/setpipestate/gle",
159 (intmax_t)gle);
161 CloseHandle(hPipe);
162 return IPC_STATE__OTHER_ERROR;
165 *pfd = _open_osfhandle((intptr_t)hPipe, O_RDWR|O_BINARY);
166 if (*pfd < 0) {
167 gle = GetLastError();
168 trace2_data_intmax("ipc-debug", NULL,
169 "connect/openosfhandle/gle",
170 (intmax_t)gle);
172 CloseHandle(hPipe);
173 return IPC_STATE__OTHER_ERROR;
176 /* fd now owns hPipe */
178 return IPC_STATE__LISTENING;
182 * The default connection timeout for Windows clients.
184 * This is not currently part of the ipc_ API (nor the config settings)
185 * because of differences between Windows and other platforms.
187 * This value was chosen at random.
189 #define WINDOWS_CONNECTION_TIMEOUT_MS (30000)
191 enum ipc_active_state ipc_client_try_connect(
192 const char *path,
193 const struct ipc_client_connect_options *options,
194 struct ipc_client_connection **p_connection)
196 wchar_t wpath[MAX_PATH];
197 enum ipc_active_state state = IPC_STATE__OTHER_ERROR;
198 int fd = -1;
200 *p_connection = NULL;
202 trace2_region_enter("ipc-client", "try-connect", NULL);
203 trace2_data_string("ipc-client", NULL, "try-connect/path", path);
205 if (initialize_pipe_name(path, wpath, ARRAY_SIZE(wpath)) < 0)
206 state = IPC_STATE__INVALID_PATH;
207 else
208 state = connect_to_server(wpath, WINDOWS_CONNECTION_TIMEOUT_MS,
209 options, &fd);
211 trace2_data_intmax("ipc-client", NULL, "try-connect/state",
212 (intmax_t)state);
213 trace2_region_leave("ipc-client", "try-connect", NULL);
215 if (state == IPC_STATE__LISTENING) {
216 (*p_connection) = xcalloc(1, sizeof(struct ipc_client_connection));
217 (*p_connection)->fd = fd;
220 return state;
223 void ipc_client_close_connection(struct ipc_client_connection *connection)
225 if (!connection)
226 return;
228 if (connection->fd != -1)
229 close(connection->fd);
231 free(connection);
234 int ipc_client_send_command_to_connection(
235 struct ipc_client_connection *connection,
236 const char *message, size_t message_len,
237 struct strbuf *answer)
239 int ret = 0;
241 strbuf_setlen(answer, 0);
243 trace2_region_enter("ipc-client", "send-command", NULL);
245 if (write_packetized_from_buf_no_flush(message, message_len,
246 connection->fd) < 0 ||
247 packet_flush_gently(connection->fd) < 0) {
248 ret = error(_("could not send IPC command"));
249 goto done;
252 FlushFileBuffers((HANDLE)_get_osfhandle(connection->fd));
254 if (read_packetized_to_strbuf(
255 connection->fd, answer,
256 PACKET_READ_GENTLE_ON_EOF | PACKET_READ_GENTLE_ON_READ_ERROR) < 0) {
257 ret = error(_("could not read IPC response"));
258 goto done;
261 done:
262 trace2_region_leave("ipc-client", "send-command", NULL);
263 return ret;
266 int ipc_client_send_command(const char *path,
267 const struct ipc_client_connect_options *options,
268 const char *message, size_t message_len,
269 struct strbuf *response)
271 int ret = -1;
272 enum ipc_active_state state;
273 struct ipc_client_connection *connection = NULL;
275 state = ipc_client_try_connect(path, options, &connection);
277 if (state != IPC_STATE__LISTENING)
278 return ret;
280 ret = ipc_client_send_command_to_connection(connection,
281 message, message_len,
282 response);
284 ipc_client_close_connection(connection);
286 return ret;
290 * Duplicate the given pipe handle and wrap it in a file descriptor so
291 * that we can use pkt-line on it.
293 static int dup_fd_from_pipe(const HANDLE pipe)
295 HANDLE process = GetCurrentProcess();
296 HANDLE handle;
297 int fd;
299 if (!DuplicateHandle(process, pipe, process, &handle, 0, FALSE,
300 DUPLICATE_SAME_ACCESS)) {
301 errno = err_win_to_posix(GetLastError());
302 return -1;
305 fd = _open_osfhandle((intptr_t)handle, O_RDWR|O_BINARY);
306 if (fd < 0) {
307 errno = err_win_to_posix(GetLastError());
308 CloseHandle(handle);
309 return -1;
313 * `handle` is now owned by `fd` and will be automatically closed
314 * when the descriptor is closed.
317 return fd;
321 * Magic numbers used to annotate callback instance data.
322 * These are used to help guard against accidentally passing the
323 * wrong instance data across multiple levels of callbacks (which
324 * is easy to do if there are `void*` arguments).
326 enum magic {
327 MAGIC_SERVER_REPLY_DATA,
328 MAGIC_SERVER_THREAD_DATA,
329 MAGIC_SERVER_DATA,
332 struct ipc_server_reply_data {
333 enum magic magic;
334 int fd;
335 struct ipc_server_thread_data *server_thread_data;
338 struct ipc_server_thread_data {
339 enum magic magic;
340 struct ipc_server_thread_data *next_thread;
341 struct ipc_server_data *server_data;
342 pthread_t pthread_id;
343 HANDLE hPipe;
347 * On Windows, the conceptual "ipc-server" is implemented as a pool of
348 * n idential/peer "server-thread" threads. That is, there is no
349 * hierarchy of threads; and therefore no controller thread managing
350 * the pool. Each thread has an independent handle to the named pipe,
351 * receives incoming connections, processes the client, and re-uses
352 * the pipe for the next client connection.
354 * Therefore, the "ipc-server" only needs to maintain a list of the
355 * spawned threads for eventual "join" purposes.
357 * A single "stop-event" is visible to all of the server threads to
358 * tell them to shutdown (when idle).
360 struct ipc_server_data {
361 enum magic magic;
362 ipc_server_application_cb *application_cb;
363 void *application_data;
364 struct strbuf buf_path;
365 wchar_t wpath[MAX_PATH];
367 HANDLE hEventStopRequested;
368 struct ipc_server_thread_data *thread_list;
369 int is_stopped;
372 enum connect_result {
373 CR_CONNECTED = 0,
374 CR_CONNECT_PENDING,
375 CR_CONNECT_ERROR,
376 CR_WAIT_ERROR,
377 CR_SHUTDOWN,
380 static enum connect_result queue_overlapped_connect(
381 struct ipc_server_thread_data *server_thread_data,
382 OVERLAPPED *lpo)
384 if (ConnectNamedPipe(server_thread_data->hPipe, lpo))
385 goto failed;
387 switch (GetLastError()) {
388 case ERROR_IO_PENDING:
389 return CR_CONNECT_PENDING;
391 case ERROR_PIPE_CONNECTED:
392 SetEvent(lpo->hEvent);
393 return CR_CONNECTED;
395 default:
396 break;
399 failed:
400 error(_("ConnectNamedPipe failed for '%s' (%lu)"),
401 server_thread_data->server_data->buf_path.buf,
402 GetLastError());
403 return CR_CONNECT_ERROR;
407 * Use Windows Overlapped IO to wait for a connection or for our event
408 * to be signalled.
410 static enum connect_result wait_for_connection(
411 struct ipc_server_thread_data *server_thread_data,
412 OVERLAPPED *lpo)
414 enum connect_result r;
415 HANDLE waitHandles[2];
416 DWORD dwWaitResult;
418 r = queue_overlapped_connect(server_thread_data, lpo);
419 if (r != CR_CONNECT_PENDING)
420 return r;
422 waitHandles[0] = server_thread_data->server_data->hEventStopRequested;
423 waitHandles[1] = lpo->hEvent;
425 dwWaitResult = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
426 switch (dwWaitResult) {
427 case WAIT_OBJECT_0 + 0:
428 return CR_SHUTDOWN;
430 case WAIT_OBJECT_0 + 1:
431 ResetEvent(lpo->hEvent);
432 return CR_CONNECTED;
434 default:
435 return CR_WAIT_ERROR;
440 * Forward declare our reply callback function so that any compiler
441 * errors are reported when we actually define the function (in addition
442 * to any errors reported when we try to pass this callback function as
443 * a parameter in a function call). The former are easier to understand.
445 static ipc_server_reply_cb do_io_reply_callback;
448 * Relay application's response message to the client process.
449 * (We do not flush at this point because we allow the caller
450 * to chunk data to the client thru us.)
452 static int do_io_reply_callback(struct ipc_server_reply_data *reply_data,
453 const char *response, size_t response_len)
455 if (reply_data->magic != MAGIC_SERVER_REPLY_DATA)
456 BUG("reply_cb called with wrong instance data");
458 return write_packetized_from_buf_no_flush(response, response_len,
459 reply_data->fd);
463 * Receive the request/command from the client and pass it to the
464 * registered request-callback. The request-callback will compose
465 * a response and call our reply-callback to send it to the client.
467 * Simple-IPC only contains one round trip, so we flush and close
468 * here after the response.
470 static int do_io(struct ipc_server_thread_data *server_thread_data)
472 struct strbuf buf = STRBUF_INIT;
473 struct ipc_server_reply_data reply_data;
474 int ret = 0;
476 reply_data.magic = MAGIC_SERVER_REPLY_DATA;
477 reply_data.server_thread_data = server_thread_data;
479 reply_data.fd = dup_fd_from_pipe(server_thread_data->hPipe);
480 if (reply_data.fd < 0)
481 return error(_("could not create fd from pipe for '%s'"),
482 server_thread_data->server_data->buf_path.buf);
484 ret = read_packetized_to_strbuf(
485 reply_data.fd, &buf,
486 PACKET_READ_GENTLE_ON_EOF | PACKET_READ_GENTLE_ON_READ_ERROR);
487 if (ret >= 0) {
488 ret = server_thread_data->server_data->application_cb(
489 server_thread_data->server_data->application_data,
490 buf.buf, buf.len, do_io_reply_callback, &reply_data);
492 packet_flush_gently(reply_data.fd);
494 FlushFileBuffers((HANDLE)_get_osfhandle((reply_data.fd)));
496 else {
498 * The client probably disconnected/shutdown before it
499 * could send a well-formed message. Ignore it.
503 strbuf_release(&buf);
504 close(reply_data.fd);
506 return ret;
510 * Handle IPC request and response with this connected client. And reset
511 * the pipe to prepare for the next client.
513 static int use_connection(struct ipc_server_thread_data *server_thread_data)
515 int ret;
517 ret = do_io(server_thread_data);
519 FlushFileBuffers(server_thread_data->hPipe);
520 DisconnectNamedPipe(server_thread_data->hPipe);
522 return ret;
526 * Thread proc for an IPC server worker thread. It handles a series of
527 * connections from clients. It cleans and reuses the hPipe between each
528 * client.
530 static void *server_thread_proc(void *_server_thread_data)
532 struct ipc_server_thread_data *server_thread_data = _server_thread_data;
533 HANDLE hEventConnected = INVALID_HANDLE_VALUE;
534 OVERLAPPED oConnect;
535 enum connect_result cr;
536 int ret;
538 assert(server_thread_data->hPipe != INVALID_HANDLE_VALUE);
540 trace2_thread_start("ipc-server");
541 trace2_data_string("ipc-server", NULL, "pipe",
542 server_thread_data->server_data->buf_path.buf);
544 hEventConnected = CreateEventW(NULL, TRUE, FALSE, NULL);
546 memset(&oConnect, 0, sizeof(oConnect));
547 oConnect.hEvent = hEventConnected;
549 for (;;) {
550 cr = wait_for_connection(server_thread_data, &oConnect);
552 switch (cr) {
553 case CR_SHUTDOWN:
554 goto finished;
556 case CR_CONNECTED:
557 ret = use_connection(server_thread_data);
558 if (ret == SIMPLE_IPC_QUIT) {
559 ipc_server_stop_async(
560 server_thread_data->server_data);
561 goto finished;
563 if (ret > 0) {
565 * Ignore (transient) IO errors with this
566 * client and reset for the next client.
569 break;
571 case CR_CONNECT_PENDING:
572 /* By construction, this should not happen. */
573 BUG("ipc-server[%s]: unexpeced CR_CONNECT_PENDING",
574 server_thread_data->server_data->buf_path.buf);
576 case CR_CONNECT_ERROR:
577 case CR_WAIT_ERROR:
579 * Ignore these theoretical errors.
581 DisconnectNamedPipe(server_thread_data->hPipe);
582 break;
584 default:
585 BUG("unandled case after wait_for_connection");
589 finished:
590 CloseHandle(server_thread_data->hPipe);
591 CloseHandle(hEventConnected);
593 trace2_thread_exit();
594 return NULL;
598 * We need to build a Windows "SECURITY_ATTRIBUTES" object and use it
599 * to apply an ACL when we create the initial instance of the Named
600 * Pipe. The construction is somewhat involved and consists of
601 * several sequential steps and intermediate objects.
603 * We use this structure to hold these intermediate pointers so that
604 * we can free them as a group. (It is unclear from the docs whether
605 * some of these intermediate pointers can be freed before we are
606 * finished using the "lpSA" member.)
608 struct my_sa_data
610 PSID pEveryoneSID;
611 PACL pACL;
612 PSECURITY_DESCRIPTOR pSD;
613 LPSECURITY_ATTRIBUTES lpSA;
616 static void init_sa(struct my_sa_data *d)
618 memset(d, 0, sizeof(*d));
621 static void release_sa(struct my_sa_data *d)
623 if (d->pEveryoneSID)
624 FreeSid(d->pEveryoneSID);
625 if (d->pACL)
626 LocalFree(d->pACL);
627 if (d->pSD)
628 LocalFree(d->pSD);
629 if (d->lpSA)
630 LocalFree(d->lpSA);
632 memset(d, 0, sizeof(*d));
636 * Create SECURITY_ATTRIBUTES to apply to the initial named pipe. The
637 * creator of the first server instance gets to set the ACLs on it.
639 * We allow the well-known group `EVERYONE` to have read+write access
640 * to the named pipe so that clients can send queries to the daemon
641 * and receive the response.
643 * Normally, this is not necessary since the daemon is usually
644 * automatically started by a foreground command like `git status`,
645 * but in those cases where an elevated Git command started the daemon
646 * (such that the daemon itself runs with elevation), we need to add
647 * the ACL so that non-elevated commands can write to it.
649 * The following document was helpful:
650 * https://docs.microsoft.com/en-us/windows/win32/secauthz/creating-a-security-descriptor-for-a-new-object-in-c--
652 * Returns d->lpSA set to a SA or NULL.
654 static LPSECURITY_ATTRIBUTES get_sa(struct my_sa_data *d)
656 SID_IDENTIFIER_AUTHORITY sid_auth_world = SECURITY_WORLD_SID_AUTHORITY;
657 #define NR_EA (1)
658 EXPLICIT_ACCESS ea[NR_EA];
659 DWORD dwResult;
661 if (!AllocateAndInitializeSid(&sid_auth_world, 1,
662 SECURITY_WORLD_RID, 0,0,0,0,0,0,0,
663 &d->pEveryoneSID)) {
664 DWORD gle = GetLastError();
665 trace2_data_intmax("ipc-debug", NULL, "alloc-world-sid/gle",
666 (intmax_t)gle);
667 goto fail;
670 memset(ea, 0, NR_EA * sizeof(EXPLICIT_ACCESS));
672 ea[0].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE;
673 ea[0].grfAccessMode = SET_ACCESS;
674 ea[0].grfInheritance = NO_INHERITANCE;
675 ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
676 ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
677 ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
678 ea[0].Trustee.ptstrName = (LPTSTR)d->pEveryoneSID;
680 dwResult = SetEntriesInAcl(NR_EA, ea, NULL, &d->pACL);
681 if (dwResult != ERROR_SUCCESS) {
682 DWORD gle = GetLastError();
683 trace2_data_intmax("ipc-debug", NULL, "set-acl-entry/gle",
684 (intmax_t)gle);
685 trace2_data_intmax("ipc-debug", NULL, "set-acl-entry/dw",
686 (intmax_t)dwResult);
687 goto fail;
690 d->pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
691 LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
692 if (!InitializeSecurityDescriptor(d->pSD, SECURITY_DESCRIPTOR_REVISION)) {
693 DWORD gle = GetLastError();
694 trace2_data_intmax("ipc-debug", NULL, "init-sd/gle", (intmax_t)gle);
695 goto fail;
698 if (!SetSecurityDescriptorDacl(d->pSD, TRUE, d->pACL, FALSE)) {
699 DWORD gle = GetLastError();
700 trace2_data_intmax("ipc-debug", NULL, "set-sd-dacl/gle", (intmax_t)gle);
701 goto fail;
704 d->lpSA = (LPSECURITY_ATTRIBUTES)LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES));
705 d->lpSA->nLength = sizeof(SECURITY_ATTRIBUTES);
706 d->lpSA->lpSecurityDescriptor = d->pSD;
707 d->lpSA->bInheritHandle = FALSE;
709 return d->lpSA;
711 fail:
712 release_sa(d);
713 return NULL;
716 static HANDLE create_new_pipe(wchar_t *wpath, int is_first)
718 HANDLE hPipe;
719 DWORD dwOpenMode, dwPipeMode;
720 struct my_sa_data my_sa_data;
722 init_sa(&my_sa_data);
724 dwOpenMode = PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND |
725 FILE_FLAG_OVERLAPPED;
727 dwPipeMode = PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE | PIPE_WAIT |
728 PIPE_REJECT_REMOTE_CLIENTS;
730 if (is_first) {
731 dwOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
734 * On Windows, the first server pipe instance gets to
735 * set the ACL / Security Attributes on the named
736 * pipe; subsequent instances inherit and cannot
737 * change them.
739 get_sa(&my_sa_data);
742 hPipe = CreateNamedPipeW(wpath, dwOpenMode, dwPipeMode,
743 PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0,
744 my_sa_data.lpSA);
746 release_sa(&my_sa_data);
748 return hPipe;
751 int ipc_server_run_async(struct ipc_server_data **returned_server_data,
752 const char *path, const struct ipc_server_opts *opts,
753 ipc_server_application_cb *application_cb,
754 void *application_data)
756 struct ipc_server_data *server_data;
757 wchar_t wpath[MAX_PATH];
758 HANDLE hPipeFirst = INVALID_HANDLE_VALUE;
759 int k;
760 int ret = 0;
761 int nr_threads = opts->nr_threads;
763 *returned_server_data = NULL;
765 ret = initialize_pipe_name(path, wpath, ARRAY_SIZE(wpath));
766 if (ret < 0) {
767 errno = EINVAL;
768 return -1;
771 hPipeFirst = create_new_pipe(wpath, 1);
772 if (hPipeFirst == INVALID_HANDLE_VALUE) {
773 errno = EADDRINUSE;
774 return -2;
777 server_data = xcalloc(1, sizeof(*server_data));
778 server_data->magic = MAGIC_SERVER_DATA;
779 server_data->application_cb = application_cb;
780 server_data->application_data = application_data;
781 server_data->hEventStopRequested = CreateEvent(NULL, TRUE, FALSE, NULL);
782 strbuf_init(&server_data->buf_path, 0);
783 strbuf_addstr(&server_data->buf_path, path);
784 wcscpy(server_data->wpath, wpath);
786 if (nr_threads < 1)
787 nr_threads = 1;
789 for (k = 0; k < nr_threads; k++) {
790 struct ipc_server_thread_data *std;
792 std = xcalloc(1, sizeof(*std));
793 std->magic = MAGIC_SERVER_THREAD_DATA;
794 std->server_data = server_data;
795 std->hPipe = INVALID_HANDLE_VALUE;
797 std->hPipe = (k == 0)
798 ? hPipeFirst
799 : create_new_pipe(server_data->wpath, 0);
801 if (std->hPipe == INVALID_HANDLE_VALUE) {
803 * If we've reached a pipe instance limit for
804 * this path, just use fewer threads.
806 free(std);
807 break;
810 if (pthread_create(&std->pthread_id, NULL,
811 server_thread_proc, std)) {
813 * Likewise, if we're out of threads, just use
814 * fewer threads than requested.
816 * However, we just give up if we can't even get
817 * one thread. This should not happen.
819 if (k == 0)
820 die(_("could not start thread[0] for '%s'"),
821 path);
823 CloseHandle(std->hPipe);
824 free(std);
825 break;
828 std->next_thread = server_data->thread_list;
829 server_data->thread_list = std;
832 *returned_server_data = server_data;
833 return 0;
836 int ipc_server_stop_async(struct ipc_server_data *server_data)
838 if (!server_data)
839 return 0;
842 * Gently tell all of the ipc_server threads to shutdown.
843 * This will be seen the next time they are idle (and waiting
844 * for a connection).
846 * We DO NOT attempt to force them to drop an active connection.
848 SetEvent(server_data->hEventStopRequested);
849 return 0;
852 int ipc_server_await(struct ipc_server_data *server_data)
854 DWORD dwWaitResult;
856 if (!server_data)
857 return 0;
859 dwWaitResult = WaitForSingleObject(server_data->hEventStopRequested, INFINITE);
860 if (dwWaitResult != WAIT_OBJECT_0)
861 return error(_("wait for hEvent failed for '%s'"),
862 server_data->buf_path.buf);
864 while (server_data->thread_list) {
865 struct ipc_server_thread_data *std = server_data->thread_list;
867 pthread_join(std->pthread_id, NULL);
869 server_data->thread_list = std->next_thread;
870 free(std);
873 server_data->is_stopped = 1;
875 return 0;
878 void ipc_server_free(struct ipc_server_data *server_data)
880 if (!server_data)
881 return;
883 if (!server_data->is_stopped)
884 BUG("cannot free ipc-server while running for '%s'",
885 server_data->buf_path.buf);
887 strbuf_release(&server_data->buf_path);
889 if (server_data->hEventStopRequested != INVALID_HANDLE_VALUE)
890 CloseHandle(server_data->hEventStopRequested);
892 while (server_data->thread_list) {
893 struct ipc_server_thread_data *std = server_data->thread_list;
895 server_data->thread_list = std->next_thread;
896 free(std);
899 free(server_data);