Mercurial > vim
comparison src/os_mswin.c @ 11211:71311d899b42 v8.0.0492
patch 8.0.0492: a failing client-server request can make Vim hang
commit https://github.com/vim/vim/commit/81b9d0bd5c705815e903e671e81b0b05828efd9c
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Mar 19 21:20:53 2017 +0100
patch 8.0.0492: a failing client-server request can make Vim hang
Problem: A failing client-server request can make Vim hang.
Solution: Add a timeout argument to functions that wait.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 19 Mar 2017 21:30:05 +0100 |
parents | 515db00c4676 |
children | 2e4877acfe0a |
comparison
equal
deleted
inserted
replaced
11210:5ffe3a7f9bd7 | 11211:71311d899b42 |
---|---|
2399 char_u *name, /* Where to send. */ | 2399 char_u *name, /* Where to send. */ |
2400 char_u *cmd, /* What to send. */ | 2400 char_u *cmd, /* What to send. */ |
2401 char_u **result, /* Result of eval'ed expression */ | 2401 char_u **result, /* Result of eval'ed expression */ |
2402 void *ptarget, /* HWND of server */ | 2402 void *ptarget, /* HWND of server */ |
2403 int asExpr, /* Expression or keys? */ | 2403 int asExpr, /* Expression or keys? */ |
2404 int timeout, /* timeout in seconds or zero */ | |
2404 int silent) /* don't complain about no server */ | 2405 int silent) /* don't complain about no server */ |
2405 { | 2406 { |
2406 HWND target; | 2407 HWND target; |
2407 COPYDATASTRUCT data; | 2408 COPYDATASTRUCT data; |
2408 char_u *retval = NULL; | 2409 char_u *retval = NULL; |
2442 if (SendMessage(target, WM_COPYDATA, (WPARAM)message_window, | 2443 if (SendMessage(target, WM_COPYDATA, (WPARAM)message_window, |
2443 (LPARAM)(&data)) == 0) | 2444 (LPARAM)(&data)) == 0) |
2444 return -1; | 2445 return -1; |
2445 | 2446 |
2446 if (asExpr) | 2447 if (asExpr) |
2447 retval = serverGetReply(target, &retcode, TRUE, TRUE); | 2448 retval = serverGetReply(target, &retcode, TRUE, TRUE, timeout); |
2448 | 2449 |
2449 if (result == NULL) | 2450 if (result == NULL) |
2450 vim_free(retval); | 2451 vim_free(retval); |
2451 else | 2452 else |
2452 *result = retval; /* Caller assumes responsibility for freeing */ | 2453 *result = retval; /* Caller assumes responsibility for freeing */ |
2519 * When non NULL, point to return code. 0 => OK, -1 => ERROR | 2520 * When non NULL, point to return code. 0 => OK, -1 => ERROR |
2520 * If "remove" is TRUE, consume the message, the caller must free it then. | 2521 * If "remove" is TRUE, consume the message, the caller must free it then. |
2521 * if "wait" is TRUE block until a message arrives (or the server exits). | 2522 * if "wait" is TRUE block until a message arrives (or the server exits). |
2522 */ | 2523 */ |
2523 char_u * | 2524 char_u * |
2524 serverGetReply(HWND server, int *expr_res, int remove, int wait) | 2525 serverGetReply(HWND server, int *expr_res, int remove, int wait, int timeout) |
2525 { | 2526 { |
2526 int i; | 2527 int i; |
2527 char_u *reply; | 2528 char_u *reply; |
2528 reply_T *rep; | 2529 reply_T *rep; |
2529 int did_process = FALSE; | 2530 int did_process = FALSE; |
2531 time_t start; | |
2532 time_t now; | |
2530 | 2533 |
2531 /* When waiting, loop until the message waiting for is received. */ | 2534 /* When waiting, loop until the message waiting for is received. */ |
2535 time(&start); | |
2532 for (;;) | 2536 for (;;) |
2533 { | 2537 { |
2534 /* Reset this here, in case a message arrives while we are going | 2538 /* Reset this here, in case a message arrives while we are going |
2535 * through the already received messages. */ | 2539 * through the already received messages. */ |
2536 reply_received = 0; | 2540 reply_received = 0; |
2582 while (reply_received == 0) | 2586 while (reply_received == 0) |
2583 { | 2587 { |
2584 #ifdef FEAT_TIMERS | 2588 #ifdef FEAT_TIMERS |
2585 check_due_timer(); | 2589 check_due_timer(); |
2586 #endif | 2590 #endif |
2591 time(&now); | |
2592 if (timeout > 0 && (now - start) >= timeout) | |
2593 break; | |
2594 | |
2587 /* Wait for a SendMessage() call to us. This could be the reply | 2595 /* Wait for a SendMessage() call to us. This could be the reply |
2588 * we are waiting for. Use a timeout of a second, to catch the | 2596 * we are waiting for. Use a timeout of a second, to catch the |
2589 * situation that the server died unexpectedly. */ | 2597 * situation that the server died unexpectedly. */ |
2590 MsgWaitForMultipleObjects(0, NULL, TRUE, 1000, QS_ALLINPUT); | 2598 MsgWaitForMultipleObjects(0, NULL, TRUE, 1000, QS_ALLINPUT); |
2591 | 2599 |