system/core
Révision | f0738997eac7c562371a05ef7f21ba95e0553ad4 (tree) |
---|---|
l'heure | 2016-09-07 15:06:40 |
Auteur | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Revert "adb: sockets: fix race condition between input_thread and fdevent callback"
This reverts commit 3e872c4ce7d83fee2673694644559f6fa9bdcbe0.
@@ -85,13 +85,6 @@ struct asocket { | ||
85 | 85 | ** but packets are still queued for delivery |
86 | 86 | */ |
87 | 87 | int closing; |
88 | - /* flag: set when this socket is running. | |
89 | - */ | |
90 | - int running; | |
91 | - /* flag: force close this socket. if this socket is running, other | |
92 | - ** thread set this flag to request close it. | |
93 | - */ | |
94 | - int force_close; | |
95 | 88 | |
96 | 89 | /* flag: quit adbd when both ends close the |
97 | 90 | ** local service socket |
@@ -53,13 +53,16 @@ static asocket local_socket_closing_list = { | ||
53 | 53 | .prev = &local_socket_closing_list, |
54 | 54 | }; |
55 | 55 | |
56 | -static asocket * | |
57 | -find_socket_in_list(asocket *list, unsigned local_id, unsigned peer_id) | |
56 | +// Parse the global list of sockets to find one with id |local_id|. | |
57 | +// If |peer_id| is not 0, also check that it is connected to a peer | |
58 | +// with id |peer_id|. Returns an asocket handle on success, NULL on failure. | |
59 | +asocket *find_local_socket(unsigned local_id, unsigned peer_id) | |
58 | 60 | { |
59 | 61 | asocket *s; |
60 | 62 | asocket *result = NULL; |
61 | 63 | |
62 | - for (s = list->next; s != list; s = s->next) { | |
64 | + adb_mutex_lock(&socket_list_lock); | |
65 | + for (s = local_socket_list.next; s != &local_socket_list; s = s->next) { | |
63 | 66 | if (s->id != local_id) |
64 | 67 | continue; |
65 | 68 | if (peer_id == 0 || (s->peer && s->peer->id == peer_id)) { |
@@ -67,21 +70,8 @@ find_socket_in_list(asocket *list, unsigned local_id, unsigned peer_id) | ||
67 | 70 | } |
68 | 71 | break; |
69 | 72 | } |
70 | - | |
71 | - return result; | |
72 | -} | |
73 | - | |
74 | - | |
75 | -// Parse the global list of sockets to find one with id |local_id|. | |
76 | -// If |peer_id| is not 0, also check that it is connected to a peer | |
77 | -// with id |peer_id|. Returns an asocket handle on success, NULL on failure. | |
78 | -asocket *find_local_socket(unsigned local_id, unsigned peer_id) | |
79 | -{ | |
80 | - asocket *result = NULL; | |
81 | - | |
82 | - adb_mutex_lock(&socket_list_lock); | |
83 | - result = find_socket_in_list(&local_socket_list, local_id, peer_id); | |
84 | 73 | adb_mutex_unlock(&socket_list_lock); |
74 | + | |
85 | 75 | return result; |
86 | 76 | } |
87 | 77 |
@@ -123,14 +113,10 @@ void remove_socket(asocket *s) | ||
123 | 113 | } |
124 | 114 | } |
125 | 115 | |
126 | -// Note: after return, all sockets refer to transport @t should be closed. | |
127 | -// (Because the atransport is going to removed.) | |
128 | -// force_close && running flag are to implement this. | |
129 | 116 | void close_all_sockets(atransport *t) |
130 | 117 | { |
131 | 118 | asocket *s; |
132 | 119 | |
133 | - D("close all sockets of transport %p\n", t); | |
134 | 120 | /* this is a little gross, but since s->close() *will* modify |
135 | 121 | ** the list out from under you, your options are limited. |
136 | 122 | */ |
@@ -138,17 +124,7 @@ void close_all_sockets(atransport *t) | ||
138 | 124 | restart: |
139 | 125 | for(s = local_socket_list.next; s != &local_socket_list; s = s->next){ |
140 | 126 | if(s->transport == t || (s->peer && s->peer->transport == t)) { |
141 | - // set force_close flag since transport is going to be removed. | |
142 | - // we need ensure the socket is closed after we return. | |
143 | - s->force_close = 1; | |
144 | - // avoid race condition with pending fdevent | |
145 | - if (s->running) { | |
146 | - // unlock to give a chance to close socket after running | |
147 | - adb_mutex_unlock(&socket_list_lock); | |
148 | - adb_sleep_ms(10); // sleep to relax cpu | |
149 | - adb_mutex_lock(&socket_list_lock); | |
150 | - } else | |
151 | - local_socket_close_locked(s); | |
127 | + local_socket_close_locked(s); | |
152 | 128 | goto restart; |
153 | 129 | } |
154 | 130 | } |
@@ -217,18 +193,8 @@ static void local_socket_ready(asocket *s) | ||
217 | 193 | |
218 | 194 | static void local_socket_close(asocket *s) |
219 | 195 | { |
220 | - unsigned local_id = s->id; | |
221 | - unsigned peer_id = s->peer ? s->peer->id : 0; | |
222 | - asocket *sk; | |
223 | - | |
224 | 196 | adb_mutex_lock(&socket_list_lock); |
225 | - // we may race with close_all_sockets (called by input-thread), | |
226 | - // so need to check if socket already destoried. | |
227 | - sk = find_socket_in_list(&local_socket_list, local_id, peer_id); | |
228 | - if (!sk) | |
229 | - sk = find_socket_in_list(&local_socket_closing_list, local_id, peer_id); | |
230 | - if (sk) | |
231 | - local_socket_close_locked(s); | |
197 | + local_socket_close_locked(s); | |
232 | 198 | adb_mutex_unlock(&socket_list_lock); |
233 | 199 | } |
234 | 200 |
@@ -284,10 +250,9 @@ static void local_socket_close_locked(asocket *s) | ||
284 | 250 | } |
285 | 251 | |
286 | 252 | /* If we are already closing, or if there are no |
287 | - ** pending packets, or need force close it, then | |
288 | - ** destroy immediately. | |
253 | + ** pending packets, destroy immediately | |
289 | 254 | */ |
290 | - if (s->closing || s->force_close || s->pkt_first == NULL) { | |
255 | + if (s->closing || s->pkt_first == NULL) { | |
291 | 256 | int id = s->id; |
292 | 257 | local_socket_destroy(s); |
293 | 258 | D("LS(%d): closed\n", id); |
@@ -307,12 +272,8 @@ static void local_socket_close_locked(asocket *s) | ||
307 | 272 | static void local_socket_event_func(int fd, unsigned ev, void* _s) |
308 | 273 | { |
309 | 274 | asocket* s = reinterpret_cast<asocket*>(_s); |
310 | - s->running = 1; | |
311 | 275 | D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev); |
312 | 276 | |
313 | - if (s->force_close) | |
314 | - goto out; | |
315 | - | |
316 | 277 | /* put the FDE_WRITE processing before the FDE_READ |
317 | 278 | ** in order to simplify the code. |
318 | 279 | */ |
@@ -326,7 +287,7 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
326 | 287 | ** be processed in the next iteration loop |
327 | 288 | */ |
328 | 289 | if (errno == EAGAIN) { |
329 | - goto out; | |
290 | + return; | |
330 | 291 | } |
331 | 292 | } else if (r > 0) { |
332 | 293 | p->ptr += r; |
@@ -335,7 +296,6 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
335 | 296 | } |
336 | 297 | |
337 | 298 | D(" closing after write because r=%d and errno is %d\n", r, errno); |
338 | - s->running = 0; | |
339 | 299 | s->close(s); |
340 | 300 | return; |
341 | 301 | } |
@@ -354,7 +314,6 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
354 | 314 | */ |
355 | 315 | if (s->closing) { |
356 | 316 | D(" closing because 'closing' is set after write\n"); |
357 | - s->running = 0; | |
358 | 317 | s->close(s); |
359 | 318 | return; |
360 | 319 | } |
@@ -413,7 +372,7 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
413 | 372 | ** this handler function will be called again |
414 | 373 | ** to process FDE_WRITE events. |
415 | 374 | */ |
416 | - goto out; | |
375 | + return; | |
417 | 376 | } |
418 | 377 | |
419 | 378 | if (r > 0) { |
@@ -428,9 +387,7 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
428 | 387 | if ((s->fde.force_eof && !r) || is_eof) { |
429 | 388 | D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n", |
430 | 389 | is_eof, r, s->fde.force_eof); |
431 | - s->running = 0; | |
432 | 390 | s->close(s); |
433 | - return; | |
434 | 391 | } |
435 | 392 | } |
436 | 393 |
@@ -441,13 +398,7 @@ static void local_socket_event_func(int fd, unsigned ev, void* _s) | ||
441 | 398 | */ |
442 | 399 | D("LS(%d): FDE_ERROR (fd=%d)\n", s->id, s->fd); |
443 | 400 | |
444 | - goto out; | |
445 | - } | |
446 | -out: | |
447 | - s->running = 0; | |
448 | - if (s->force_close) { | |
449 | - D("LS(%d): force closing (fd=%d)\n", s->id, s->fd); | |
450 | - s->close(s); | |
401 | + return; | |
451 | 402 | } |
452 | 403 | } |
453 | 404 |
@@ -455,7 +406,6 @@ asocket *create_local_socket(int fd) | ||
455 | 406 | { |
456 | 407 | asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); |
457 | 408 | if (s == NULL) fatal("cannot allocate socket"); |
458 | - memset(s, 0, sizeof(asocket)); | |
459 | 409 | s->fd = fd; |
460 | 410 | s->enqueue = local_socket_enqueue; |
461 | 411 | s->ready = local_socket_ready; |
@@ -601,7 +551,6 @@ asocket *create_remote_socket(unsigned id, atransport *t) | ||
601 | 551 | adisconnect* dis = &reinterpret_cast<aremotesocket*>(s)->disconnect; |
602 | 552 | |
603 | 553 | if (s == NULL) fatal("cannot allocate socket"); |
604 | - memset(s, 0, sizeof(asocket)); | |
605 | 554 | s->id = id; |
606 | 555 | s->enqueue = remote_socket_enqueue; |
607 | 556 | s->ready = remote_socket_ready; |
@@ -934,7 +883,6 @@ static asocket *create_smart_socket(void) | ||
934 | 883 | D("Creating smart socket \n"); |
935 | 884 | asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket))); |
936 | 885 | if (s == NULL) fatal("cannot allocate socket"); |
937 | - memset(s, 0, sizeof(asocket)); | |
938 | 886 | s->enqueue = smart_socket_enqueue; |
939 | 887 | s->ready = smart_socket_ready; |
940 | 888 | s->shutdown = NULL; |