~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/uv/test/test-async.c

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <stdio.h>
25
25
#include <stdlib.h>
26
26
 
27
 
 
28
 
static uv_prepare_t prepare_handle;
29
 
 
30
 
static uv_async_t async1_handle;
31
 
/* static uv_handle_t async2_handle; */
32
 
 
33
 
static int prepare_cb_called = 0;
34
 
 
35
 
static volatile int async1_cb_called = 0;
36
 
static int async1_closed = 0;
37
 
/* static volatile int async2_cb_called = 0; */
38
 
 
39
 
static int close_cb_called = 0;
40
 
 
41
 
static uintptr_t thread1_id = 0;
42
 
#if 0
43
 
static uintptr_t thread2_id = 0;
44
 
static uintptr_t thread3_id = 0;
45
 
#endif
46
 
 
47
 
 
48
 
/* Thread 1 makes sure that async1_cb_called reaches 3 before exiting. */
49
 
void thread1_entry(void *arg) {
50
 
  uv_sleep(50);
51
 
 
52
 
  while (1) {
53
 
    switch (async1_cb_called) {
54
 
      case 0:
55
 
        uv_async_send(&async1_handle);
56
 
        break;
57
 
 
58
 
      case 1:
59
 
        uv_async_send(&async1_handle);
60
 
        break;
61
 
 
62
 
      case 2:
63
 
        uv_async_send(&async1_handle);
64
 
        break;
65
 
 
66
 
      default:
67
 
        return;
68
 
    }
69
 
  }
70
 
}
71
 
 
72
 
#if 0
73
 
/* Thread 2 calls uv_async_send on async_handle_2 8 times. */
74
 
void thread2_entry(void *arg) {
75
 
  int i;
76
 
 
77
 
  while (1) {
78
 
    switch (async1_cb_called) {
79
 
      case 0:
80
 
        uv_async_send(&async2_handle);
81
 
        break;
82
 
 
83
 
      case 1:
84
 
        uv_async_send(&async2_handle);
85
 
        break;
86
 
 
87
 
      case 2:
88
 
        uv_async_send(&async2_handle);
89
 
        break;
90
 
    }
91
 
    uv_sleep(5);
92
 
  }
93
 
 
94
 
  if (async1_cb_called == 20) {
95
 
    uv_close(handle);
96
 
  }
97
 
}
98
 
 
99
 
 
100
 
/* Thread 3 calls uv_async_send on async_handle_2 8 times
101
 
 * after waiting half a second first.
102
 
 */
103
 
void thread3_entry(void *arg) {
104
 
  int i;
105
 
 
106
 
  for (i = 0; i < 8; i++) {
107
 
    uv_async_send(&async2_handle);
108
 
  }
109
 
}
110
 
#endif
 
27
static uv_thread_t thread;
 
28
static uv_mutex_t mutex;
 
29
 
 
30
static uv_prepare_t prepare;
 
31
static uv_async_t async;
 
32
 
 
33
static volatile int async_cb_called;
 
34
static int prepare_cb_called;
 
35
static int close_cb_called;
 
36
 
 
37
 
 
38
static void thread_cb(void *arg) {
 
39
  int n;
 
40
  int r;
 
41
 
 
42
  for (;;) {
 
43
    uv_mutex_lock(&mutex);
 
44
    n = async_cb_called;
 
45
    uv_mutex_unlock(&mutex);
 
46
 
 
47
    if (n == 3) {
 
48
      break;
 
49
    }
 
50
 
 
51
    r = uv_async_send(&async);
 
52
    ASSERT(r == 0);
 
53
 
 
54
    /* Work around a bug in Valgrind.
 
55
     *
 
56
     * Valgrind runs threads not in parallel but sequentially, i.e. one after
 
57
     * the other. It also doesn't preempt them, instead it depends on threads
 
58
     * yielding voluntarily by making a syscall.
 
59
     *
 
60
     * That never happens here: the pipe that is associated with the async
 
61
     * handle is written to once but that's too early for Valgrind's scheduler
 
62
     * to kick in. Afterwards, the thread busy-loops, starving the main thread.
 
63
     * Therefore, we yield.
 
64
     *
 
65
     * This behavior has been observed with Valgrind 3.7.0 and 3.9.0.
 
66
     */
 
67
    uv_sleep(0);
 
68
  }
 
69
}
111
70
 
112
71
 
113
72
static void close_cb(uv_handle_t* handle) {
116
75
}
117
76
 
118
77
 
119
 
static void async1_cb(uv_async_t* handle, int status) {
120
 
  ASSERT(handle == &async1_handle);
121
 
  ASSERT(status == 0);
122
 
 
123
 
  async1_cb_called++;
124
 
  printf("async1_cb #%d\n", async1_cb_called);
125
 
 
126
 
  if (async1_cb_called > 2 && !async1_closed) {
127
 
    async1_closed = 1;
128
 
    uv_close((uv_handle_t*)handle, close_cb);
129
 
  }
130
 
}
131
 
 
132
 
 
133
 
#if 0
134
 
static void async2_cb(uv_handle_t* handle, int status) {
135
 
  ASSERT(handle == &async2_handle);
136
 
  ASSERT(status == 0);
137
 
 
138
 
  async2_cb_called++;
139
 
  printf("async2_cb #%d\n", async2_cb_called);
140
 
 
141
 
  if (async2_cb_called == 16) {
142
 
    uv_close(handle);
143
 
  }
144
 
}
145
 
#endif
 
78
static void async_cb(uv_async_t* handle, int status) {
 
79
  int n;
 
80
 
 
81
  ASSERT(handle == &async);
 
82
  ASSERT(status == 0);
 
83
 
 
84
  uv_mutex_lock(&mutex);
 
85
  n = ++async_cb_called;
 
86
  uv_mutex_unlock(&mutex);
 
87
 
 
88
  if (n == 3) {
 
89
    uv_close((uv_handle_t*)&async, close_cb);
 
90
    uv_close((uv_handle_t*)&prepare, close_cb);
 
91
  }
 
92
}
146
93
 
147
94
 
148
95
static void prepare_cb(uv_prepare_t* handle, int status) {
149
 
  ASSERT(handle == &prepare_handle);
 
96
  int r;
 
97
 
 
98
  ASSERT(handle == &prepare);
150
99
  ASSERT(status == 0);
151
100
 
152
 
  switch (prepare_cb_called) {
153
 
    case 0:
154
 
      thread1_id = uv_create_thread(thread1_entry, NULL);
155
 
      ASSERT(thread1_id != 0);
156
 
      break;
157
 
 
158
 
#if 0
159
 
    case 1:
160
 
      thread2_id = uv_create_thread(thread2_entry, NULL);
161
 
      ASSERT(thread2_id != 0);
162
 
      break;
163
 
 
164
 
    case 2:
165
 
      thread3_id = uv_create_thread(thread3_entry, NULL);
166
 
      ASSERT(thread3_id != 0);
167
 
      break;
168
 
#endif
169
 
 
170
 
    case 1:
171
 
      uv_close((uv_handle_t*)handle, close_cb);
172
 
      break;
173
 
 
174
 
    default:
175
 
      FATAL("Should never get here");
176
 
  }
177
 
 
178
 
  prepare_cb_called++;
 
101
  if (prepare_cb_called++)
 
102
    return;
 
103
 
 
104
  r = uv_thread_create(&thread, thread_cb, NULL);
 
105
  ASSERT(r == 0);
 
106
  uv_mutex_unlock(&mutex);
179
107
}
180
108
 
181
109
 
182
110
TEST_IMPL(async) {
183
111
  int r;
184
112
 
185
 
  r = uv_prepare_init(uv_default_loop(), &prepare_handle);
186
 
  ASSERT(r == 0);
187
 
  r = uv_prepare_start(&prepare_handle, prepare_cb);
188
 
  ASSERT(r == 0);
189
 
 
190
 
  r = uv_async_init(uv_default_loop(), &async1_handle, async1_cb);
191
 
  ASSERT(r == 0);
192
 
 
193
 
#if 0
194
 
  r = uv_async_init(&async2_handle, async2_cb, close_cb, NULL);
195
 
  ASSERT(r == 0);
196
 
#endif
197
 
 
198
 
  r = uv_run(uv_default_loop());
199
 
  ASSERT(r == 0);
200
 
 
201
 
  r = uv_wait_thread(thread1_id);
202
 
  ASSERT(r == 0);
203
 
#if 0
204
 
  r = uv_wait_thread(thread2_id);
205
 
  ASSERT(r == 0);
206
 
  r = uv_wait_thread(thread3_id);
207
 
  ASSERT(r == 0);
208
 
#endif
209
 
 
210
 
  ASSERT(prepare_cb_called == 2);
211
 
  ASSERT(async1_cb_called > 2);
212
 
  /* ASSERT(async2_cb_called = 16); */
 
113
  r = uv_mutex_init(&mutex);
 
114
  ASSERT(r == 0);
 
115
  uv_mutex_lock(&mutex);
 
116
 
 
117
  r = uv_prepare_init(uv_default_loop(), &prepare);
 
118
  ASSERT(r == 0);
 
119
  r = uv_prepare_start(&prepare, prepare_cb);
 
120
  ASSERT(r == 0);
 
121
 
 
122
  r = uv_async_init(uv_default_loop(), &async, async_cb);
 
123
  ASSERT(r == 0);
 
124
 
 
125
  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
 
126
  ASSERT(r == 0);
 
127
 
 
128
  ASSERT(prepare_cb_called > 0);
 
129
  ASSERT(async_cb_called == 3);
213
130
  ASSERT(close_cb_called == 2);
214
131
 
 
132
  ASSERT(0 == uv_thread_join(&thread));
 
133
 
 
134
  MAKE_VALGRIND_HAPPY();
215
135
  return 0;
216
136
}