Annotation of embedaddon/curl/tests/libtest/lib1565.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9: *
10: * This software is licensed as described in the file COPYING, which
11: * you should have received as part of this distribution. The terms
12: * are also available at https://curl.haxx.se/docs/copyright.html.
13: *
14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15: * copies of the Software, and permit persons to whom the Software is
16: * furnished to do so, under the terms of the COPYING file.
17: *
18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19: * KIND, either express or implied.
20: *
21: ***************************************************************************/
22: #include "test.h"
23:
24: #include "testutil.h"
25: #include "warnless.h"
26: #include "memdebug.h"
27:
28: #ifdef HAVE_PTHREAD_H
29: #include <pthread.h>
30: #include <unistd.h>
31:
32: #define TEST_HANG_TIMEOUT 60 * 1000
33: #define CONN_NUM 3
34: #define TIME_BETWEEN_START_SECS 2
35:
36: static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
37: static CURL *pending_handles[CONN_NUM];
38: static int pending_num = 0;
39: static int test_failure = 0;
40:
41: static CURLM *multi = NULL;
42: static const char *url;
43:
44: static void *run_thread(void *ptr)
45: {
46: CURL *easy = NULL;
47: int res = 0;
48: int i;
49:
50: (void)ptr;
51:
52: for(i = 0; i < CONN_NUM; i++) {
53: sleep(TIME_BETWEEN_START_SECS);
54:
55: easy_init(easy);
56:
57: easy_setopt(easy, CURLOPT_URL, url);
58: easy_setopt(easy, CURLOPT_VERBOSE, 0L);
59:
60: pthread_mutex_lock(&lock);
61:
62: if(test_failure) {
63: pthread_mutex_unlock(&lock);
64: goto test_cleanup;
65: }
66:
67: pending_handles[pending_num] = easy;
68: pending_num++;
69: easy = NULL;
70:
71: pthread_mutex_unlock(&lock);
72:
73: multi_wakeup(multi);
74: }
75:
76: test_cleanup:
77:
78: curl_easy_cleanup(easy);
79:
80: pthread_mutex_lock(&lock);
81:
82: if(!test_failure)
83: test_failure = res;
84:
85: pthread_mutex_unlock(&lock);
86:
87: return NULL;
88: }
89:
90: int test(char *URL)
91: {
92: int still_running;
93: int num;
94: int i;
95: int res = 0;
96: CURL *started_handles[CONN_NUM];
97: int started_num = 0;
98: int finished_num = 0;
99: pthread_t tid = 0;
100: struct CURLMsg *message;
101:
102: start_test_timing();
103:
104: global_init(CURL_GLOBAL_ALL);
105:
106: multi_init(multi);
107:
108: url = URL;
109:
110: res = pthread_create(&tid, NULL, run_thread, NULL);
111: if(0 != res) {
112: fprintf(stderr, "%s:%d Couldn't create thread, errno %d\n",
113: __FILE__, __LINE__, res);
114: goto test_cleanup;
115: }
116:
117: while(1) {
118: multi_perform(multi, &still_running);
119:
120: abort_on_test_timeout();
121:
122: while((message = curl_multi_info_read(multi, &num)) != NULL) {
123: if(message->msg == CURLMSG_DONE) {
124: res = message->data.result;
125: if(res)
126: goto test_cleanup;
127: multi_remove_handle(multi, message->easy_handle);
128: finished_num++;
129: }
130: else {
131: fprintf(stderr, "%s:%d Got an unexpected message from curl: %i\n",
132: __FILE__, __LINE__, (int)message->msg);
133: res = TEST_ERR_MAJOR_BAD;
134: goto test_cleanup;
135: }
136:
137: abort_on_test_timeout();
138: }
139:
140: if(CONN_NUM == finished_num)
141: break;
142:
143: multi_poll(multi, NULL, 0, TEST_HANG_TIMEOUT, &num);
144:
145: abort_on_test_timeout();
146:
147: pthread_mutex_lock(&lock);
148:
149: while(pending_num > 0) {
150: res_multi_add_handle(multi, pending_handles[pending_num - 1]);
151: if(res) {
152: pthread_mutex_unlock(&lock);
153: goto test_cleanup;
154: }
155:
156: started_handles[started_num] = pending_handles[pending_num - 1];
157: started_num++;
158: pending_num--;
159: }
160:
161: pthread_mutex_unlock(&lock);
162:
163: abort_on_test_timeout();
164: }
165:
166: if(CONN_NUM != started_num) {
167: fprintf(stderr, "%s:%d Not all connections started: %d of %d\n",
168: __FILE__, __LINE__, started_num, CONN_NUM);
169: goto test_cleanup;
170: }
171:
172: if(CONN_NUM != finished_num) {
173: fprintf(stderr, "%s:%d Not all connections finished: %d of %d\n",
174: __FILE__, __LINE__, started_num, CONN_NUM);
175: goto test_cleanup;
176: }
177:
178: test_cleanup:
179:
180: pthread_mutex_lock(&lock);
181: if(!test_failure)
182: test_failure = res;
183: pthread_mutex_unlock(&lock);
184:
185: if(0 != tid)
186: pthread_join(tid, NULL);
187:
188: curl_multi_cleanup(multi);
189: for(i = 0; i < pending_num; i++)
190: curl_easy_cleanup(pending_handles[i]);
191: for(i = 0; i < started_num; i++)
192: curl_easy_cleanup(started_handles[i]);
193: curl_global_cleanup();
194:
195: return test_failure;
196: }
197:
198: #else /* without pthread, this test doesn't work */
199: int test(char *URL)
200: {
201: (void)URL;
202: return 0;
203: }
204: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>