Advertisement
Guest User

0050-pipe-check-and-thread-safe-read.patch

a guest
Apr 13th, 2014
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. --- wine-1.3.24/dlls/ntdll/sync.c.old 2011-12-28 16:14:53.967056791 -0800
  2. +++ wine-1.3.24/dlls/ntdll/sync.c 2011-12-28 16:14:23.639181763 -0800
  3. @@ -132,7 +132,9 @@
  4. RtlFreeHeap(GetProcessHeap(), 0, server_sd);
  5. }
  6.  
  7. -#define is_pipe_object(h) (h != INVALID_HANDLE_VALUE && HIWORD(h) != 0)
  8. +/* -1 "check environment", 0 "don't use them", 1 "do use them" */
  9. +static int s_usePipeObjects = -1;
  10. +#define is_pipe_object(h) (s_usePipeObjects == 1 && h != INVALID_HANDLE_VALUE && HIWORD(h) != 0)
  11. #define is_pipe_event(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == EVENT_MAGIC)
  12. #define is_pipe_semaphore(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == SEMAPHORE_MAGIC)
  13. #define is_pipe_mutex(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == MUTEX_MAGIC)
  14. @@ -154,13 +156,12 @@
  15. */
  16. BOOL use_pipe_objects(void)
  17. {
  18. - static const char* s_enable_pipe_sync = 0;
  19. - if (s_enable_pipe_sync == 0) {
  20. + if (s_usePipeObjects == -1) {
  21. const char* env;
  22. extern int __wine_main_argc;
  23. extern char** __wine_main_argv;
  24.  
  25. - s_enable_pipe_sync = "0";
  26. + s_usePipeObjects = 0;
  27. env = getenv("L_ENABLE_PIPE_SYNC_FOR_APP");
  28. if (env) {
  29. /* note: PEB command line is not available when this is first called so use main args */
  30. @@ -168,11 +169,11 @@
  31. ERR("bad __wine_main_argc: %d\n", __wine_main_argc);
  32. else if (strstr(__wine_main_argv[1], env) != 0) {
  33. MESSAGE("Honoring L_ENABLE_PIPE_SYNC_FOR_APP: %s (%s)\n", env, __wine_main_argv[1]);
  34. - s_enable_pipe_sync = "1";
  35. + s_usePipeObjects = 1;
  36. }
  37. }
  38. }
  39. - return(*s_enable_pipe_sync != '0');
  40. + return(s_usePipeObjects == 1);
  41. }
  42.  
  43. /******************************************************************************
  44. @@ -249,42 +250,85 @@
  45. */
  46. static NTSTATUS wait_for_pipe_object(LPPIPEOBJ pobj, const LARGE_INTEGER *timeout, int clear)
  47. {
  48. - char c;
  49. - NTSTATUS ret;
  50. - struct pollfd pfd;
  51. - int tm;
  52. -
  53. - pfd.fd = pobj->fd[0];
  54. - pfd.events = POLLIN;
  55. - pfd.revents = 0;
  56. -
  57. - if (!timeout)
  58. - tm = -1;
  59. - else
  60. - tm = (-timeout->QuadPart) / (ULONGLONG)10000;
  61. -
  62. - TRACE("%p timeout=%d\n", pobj, tm);
  63. -
  64. - if (poll(&pfd, 1, tm) == -1)
  65. - ret = WAIT_FAILED;
  66. - else if (pfd.revents & POLLIN)
  67. - {
  68. - ret = WAIT_OBJECT_0;
  69. -
  70. - TRACE("pipe object signaled before time out\n");
  71. - if (clear)
  72. - {
  73. - if (read(pobj->fd[0], &c, 1) != 1) /* Clear the signal */
  74. - {
  75. - ERR("Failed to clear pipe object\n");
  76. - ret = WAIT_FAILED;
  77. - }
  78. - }
  79. - }
  80. - else
  81. - {
  82. - TRACE("pipe object timed out\n");
  83. - ret = WAIT_TIMEOUT;
  84. + char c;
  85. + NTSTATUS ret;
  86. + struct pollfd pfd;
  87. + int tm; /* ms */
  88. + int tmAlready;
  89. + int readret;
  90. + struct timeval tv;
  91. + LONGLONG start; /* usecs */
  92. +
  93. + pfd.fd = pobj->fd[0];
  94. + pfd.events = POLLIN;
  95. + pfd.revents = 0;
  96. +
  97. + /* Remember that this is initially in get_nt_timeout format
  98. +(*-10000) */
  99. + if (!timeout)
  100. + tm = -1;
  101. + else
  102. + tm = (-timeout->QuadPart) / (ULONGLONG)10000;
  103. +
  104. + TRACE("pobj=%p timeout=%d\n", pobj, tm);
  105. +
  106. + gettimeofday(&tv, 0);
  107. + start = (LONGLONG) tv.tv_sec * 1000000LL + (LONGLONG) tv.tv_usec;
  108. + tmAlready = 0;
  109. +
  110. + while (1)
  111. + {
  112. + if (poll(&pfd, 1, tm - tmAlready) == -1) {
  113. + ret = WAIT_FAILED;
  114. + }
  115. + else if (pfd.revents & POLLIN)
  116. + {
  117. + ret = WAIT_OBJECT_0;
  118. +
  119. + TRACE("Pipe sync object: Signaled before time out\n");
  120. + if (clear)
  121. + {
  122. + /* Clear the signal */
  123. + readret = read(pobj->fd[0], &c, 1);
  124. + if (readret == -1 && errno == EAGAIN)
  125. + {
  126. + TRACE("Pipe sync object: Erroneous read; retrying\n");
  127. + if (!timeout)
  128. + continue;
  129. + else
  130. + {
  131. + LONGLONG usecs;
  132. +
  133. + /* Adjust time elapsed */
  134. + gettimeofday(&tv, 0);
  135. + usecs = (LONGLONG) tv.tv_sec * 1000000LL
  136. + + (LONGLONG) tv.tv_usec;
  137. + tmAlready = (usecs - start) / 1000;
  138. + if (tmAlready < tm)
  139. + continue;
  140. + else
  141. + {
  142. + TRACE("Pipe sync object: Timed out\n");
  143. + ret = WAIT_TIMEOUT;
  144. + }
  145. + }
  146. + }
  147. + else if (readret != 1)
  148. + {
  149. + ERR("Failed to clear pipe sync object\n");
  150. + ret = WAIT_FAILED;
  151. + }
  152. + }
  153. + }
  154. + else
  155. + {
  156. + ret = WAIT_TIMEOUT;
  157. + TRACE("Pipe sync object timed out\n");
  158. + }
  159. +
  160. + /* always break except when a thread loses the race */
  161. + /* between poll() and read() */
  162. + break;
  163. }
  164.  
  165. return ret;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement