• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revisionf5ed334364e2c8608c92f7f1f39067e8f893b5e0 (tree)
Time2016-07-20 18:01:29
AuthorDu, Changbin <changbin.du@inte...>
CommiterChih-Wei Huang

Log Message

adb: fdevent: add synchronization logic to avoid crash

The fdevent part didn't implemente any synchronization protection. This
could introduce race condition issues. Espacially when adb is used for
Android stress test, this will be a problem that can cause server side
crash.

Change-Id: I93c311ed62770afc3061ccb8b60a0abd09f7453d
Tracked-On: https://jira01.devtools.intel.com/browse/OAM-12574
Signed-off-by: Du, Changbin <changbin.du@intel.com>
Reviewed-on: https://android.intel.com:443/460313

Change Summary

Incremental Difference

--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -44,6 +44,8 @@
4444 // of the shell's pseudo-tty master. I.e. force close it.
4545 int SHELL_EXIT_NOTIFY_FD = -1;
4646
47+ADB_MUTEX_DEFINE( fdevent_lock );
48+
4749 static void fatal(const char *fn, const char *fmt, ...)
4850 {
4951 va_list ap;
@@ -210,6 +212,7 @@ static void fdevent_process()
210212 exit(1);
211213 }
212214
215+ adb_mutex_lock(&fdevent_lock);
213216 for(i = 0; i < n; i++) {
214217 struct epoll_event *ev = events + i;
215218 fde = ev->data.ptr;
@@ -229,6 +232,7 @@ static void fdevent_process()
229232 fdevent_plist_enqueue(fde);
230233 }
231234 }
235+ adb_mutex_unlock(&fdevent_lock);
232236 }
233237
234238 #else /* USE_SELECT */
@@ -364,13 +368,17 @@ static void fdevent_process()
364368 unsigned events;
365369 fd_set rfd, wfd, efd;
366370
371+ adb_mutex_lock(&fdevent_lock);
367372 memcpy(&rfd, &read_fds, sizeof(fd_set));
368373 memcpy(&wfd, &write_fds, sizeof(fd_set));
369374 memcpy(&efd, &error_fds, sizeof(fd_set));
370375
371376 dump_all_fds("pre select()");
377+ adb_mutex_unlock(&fdevent_lock);
372378
373379 n = select(select_n, &rfd, &wfd, &efd, NULL);
380+
381+ adb_mutex_lock(&fdevent_lock);
374382 int saved_errno = errno;
375383 D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
376384
@@ -378,7 +386,7 @@ static void fdevent_process()
378386
379387 if(n < 0) {
380388 switch(saved_errno) {
381- case EINTR: return;
389+ case EINTR: goto unlock;
382390 case EBADF:
383391 // Can't trust the FD sets after an error.
384392 FD_ZERO(&wfd);
@@ -387,7 +395,7 @@ static void fdevent_process()
387395 break;
388396 default:
389397 D("Unexpected select() error=%d\n", saved_errno);
390- return;
398+ goto unlock;
391399 }
392400 }
393401 if(n <= 0) {
@@ -416,6 +424,8 @@ static void fdevent_process()
416424 fdevent_plist_enqueue(fde);
417425 }
418426 }
427+unlock:
428+ adb_mutex_unlock(&fdevent_lock);
419429 }
420430
421431 #endif
@@ -500,14 +510,16 @@ static fdevent *fdevent_plist_dequeue(void)
500510 return node;
501511 }
502512
503-static void fdevent_call_fdfunc(fdevent* fde)
513+static void fdevent_call_fdfunc_locked(fdevent* fde)
504514 {
505515 unsigned events = fde->events;
506516 fde->events = 0;
507517 if(!(fde->state & FDE_PENDING)) return;
508518 fde->state &= (~FDE_PENDING);
509519 dump_fde(fde, "callback");
520+ adb_mutex_unlock(&fdevent_lock);
510521 fde->func(fde->fd, events, fde->arg);
522+ adb_mutex_lock(&fdevent_lock);
511523 }
512524
513525 static void fdevent_subproc_event_func(int fd, unsigned ev,
@@ -523,6 +535,7 @@ static void fdevent_subproc_event_func(int fd, unsigned ev,
523535 fdevent *fde = fd_table[fd];
524536 fdevent_add(fde, FDE_READ);
525537
538+ adb_mutex_lock(&fdevent_lock);
526539 if(ev & FDE_READ){
527540 int subproc_fd;
528541
@@ -532,17 +545,17 @@ static void fdevent_subproc_event_func(int fd, unsigned ev,
532545 if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
533546 D("subproc_fd %d out of range 0, fd_table_max=%d\n",
534547 subproc_fd, fd_table_max);
535- return;
548+ goto unlock;
536549 }
537550 fdevent *subproc_fde = fd_table[subproc_fd];
538551 if(!subproc_fde) {
539552 D("subproc_fd %d cleared from fd_table\n", subproc_fd);
540- return;
553+ goto unlock;
541554 }
542555 if(subproc_fde->fd != subproc_fd) {
543556 // Already reallocated?
544557 D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
545- return;
558+ goto unlock;
546559 }
547560
548561 subproc_fde->force_eof = 1;
@@ -556,17 +569,19 @@ static void fdevent_subproc_event_func(int fd, unsigned ev,
556569 // If there is data left, it will show up in the select().
557570 // This works because there is no other thread reading that
558571 // data when in this fd_func().
559- return;
572+ goto unlock;
560573 }
561574
562575 D("subproc_fde.state=%04x\n", subproc_fde->state);
563576 subproc_fde->events |= FDE_READ;
564577 if(subproc_fde->state & FDE_PENDING) {
565- return;
578+ goto unlock;
566579 }
567580 subproc_fde->state |= FDE_PENDING;
568- fdevent_call_fdfunc(subproc_fde);
581+ fdevent_call_fdfunc_locked(subproc_fde);
569582 }
583+unlock:
584+ adb_mutex_unlock(&fdevent_lock);
570585 }
571586
572587 fdevent *fdevent_create(int fd, fd_func func, void *arg)
@@ -590,6 +605,7 @@ void fdevent_destroy(fdevent *fde)
590605
591606 void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
592607 {
608+ adb_mutex_lock(&fdevent_lock);
593609 memset(fde, 0, sizeof(fdevent));
594610 fde->state = FDE_ACTIVE;
595611 fde->fd = fd;
@@ -604,10 +620,12 @@ void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
604620 dump_fde(fde, "connect");
605621 fdevent_connect(fde);
606622 fde->state |= FDE_ACTIVE;
623+ adb_mutex_unlock(&fdevent_lock);
607624 }
608625
609626 void fdevent_remove(fdevent *fde)
610627 {
628+ adb_mutex_lock(&fdevent_lock);
611629 if(fde->state & FDE_PENDING) {
612630 fdevent_plist_remove(fde);
613631 }
@@ -620,6 +638,7 @@ void fdevent_remove(fdevent *fde)
620638
621639 fde->state = 0;
622640 fde->events = 0;
641+ adb_mutex_unlock(&fdevent_lock);
623642 }
624643
625644
@@ -627,7 +646,11 @@ void fdevent_set(fdevent *fde, unsigned events)
627646 {
628647 events &= FDE_EVENTMASK;
629648
630- if((fde->state & FDE_EVENTMASK) == events) return;
649+ adb_mutex_lock(&fdevent_lock);
650+ if((fde->state & FDE_EVENTMASK) == events) {
651+ adb_mutex_unlock(&fdevent_lock);
652+ return;
653+ }
631654
632655 if(fde->state & FDE_ACTIVE) {
633656 fdevent_update(fde, events);
@@ -647,6 +670,7 @@ void fdevent_set(fdevent *fde, unsigned events)
647670 fde->state &= (~FDE_PENDING);
648671 }
649672 }
673+ adb_mutex_unlock(&fdevent_lock);
650674 }
651675
652676 void fdevent_add(fdevent *fde, unsigned events)
@@ -688,8 +712,10 @@ void fdevent_loop()
688712
689713 fdevent_process();
690714
715+ adb_mutex_lock(&fdevent_lock);
691716 while((fde = fdevent_plist_dequeue())) {
692- fdevent_call_fdfunc(fde);
717+ fdevent_call_fdfunc_locked(fde);
693718 }
719+ adb_mutex_unlock(&fdevent_lock);
694720 }
695721 }
--- a/adb/mutex_list.h
+++ b/adb/mutex_list.h
@@ -8,6 +8,7 @@
88 #endif
99 ADB_MUTEX(socket_list_lock)
1010 ADB_MUTEX(transport_lock)
11+ADB_MUTEX(fdevent_lock)
1112 #if ADB_HOST
1213 ADB_MUTEX(local_transports_lock)
1314 #endif
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -27,6 +27,9 @@
2727
2828 #include "adb.h"
2929
30+/* TODO: implemente fdevent synchronization for Windows platform. */
31+ADB_MUTEX_DEFINE( fdevent_lock );
32+
3033 extern void fatal(const char *fmt, ...);
3134
3235 /* forward declarations */