summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2014-01-09 11:31:08 +0100
committerGravatar Nikias Bassen2014-01-09 11:31:08 +0100
commitd04ce1b524f68dda6b75cfff69f70f4b4ad8e1d5 (patch)
tree3a906994c7a8e7c8120d982f00f4c6f636364a8b /src
parentbad870a5d072e5959f1adb01648dc3dbcc790b3b (diff)
downloadusbmuxd-d04ce1b524f68dda6b75cfff69f70f4b4ad8e1d5.tar.gz
usbmuxd-d04ce1b524f68dda6b75cfff69f70f4b4ad8e1d5.tar.bz2
device: make device_list access thread safe
Diffstat (limited to 'src')
-rw-r--r--src/device.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/device.c b/src/device.c
index 1e3cc83..29be9d1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31#include <string.h> 31#include <string.h>
32#include <stdint.h> 32#include <stdint.h>
33#include <inttypes.h> 33#include <inttypes.h>
34#include <pthread.h>
34#include "device.h" 35#include "device.h"
35#include "client.h" 36#include "client.h"
36#include "preflight.h" 37#include "preflight.h"
@@ -116,6 +117,7 @@ struct mux_device
116}; 117};
117 118
118static struct collection device_list; 119static struct collection device_list;
120pthread_mutex_t device_list_mutex;
119 121
120static uint64_t mstime64(void) 122static uint64_t mstime64(void)
121{ 123{
@@ -128,6 +130,7 @@ static int get_next_device_id(void)
128{ 130{
129 while(1) { 131 while(1) {
130 int ok = 1; 132 int ok = 1;
133 pthread_mutex_lock(&device_list_mutex);
131 FOREACH(struct mux_device *dev, &device_list) { 134 FOREACH(struct mux_device *dev, &device_list) {
132 if(dev->id == next_device_id) { 135 if(dev->id == next_device_id) {
133 next_device_id++; 136 next_device_id++;
@@ -135,6 +138,7 @@ static int get_next_device_id(void)
135 break; 138 break;
136 } 139 }
137 } ENDFOREACH 140 } ENDFOREACH
141 pthread_mutex_unlock(&device_list_mutex);
138 if(ok) 142 if(ok)
139 return next_device_id++; 143 return next_device_id++;
140 } 144 }
@@ -271,12 +275,14 @@ static void connection_teardown(struct mux_connection *conn)
271int device_start_connect(int device_id, uint16_t dport, struct mux_client *client) 275int device_start_connect(int device_id, uint16_t dport, struct mux_client *client)
272{ 276{
273 struct mux_device *dev = NULL; 277 struct mux_device *dev = NULL;
278 pthread_mutex_lock(&device_list_mutex);
274 FOREACH(struct mux_device *cdev, &device_list) { 279 FOREACH(struct mux_device *cdev, &device_list) {
275 if(cdev->id == device_id) { 280 if(cdev->id == device_id) {
276 dev = cdev; 281 dev = cdev;
277 break; 282 break;
278 } 283 }
279 } ENDFOREACH 284 } ENDFOREACH
285 pthread_mutex_unlock(&device_list_mutex);
280 if(!dev) { 286 if(!dev) {
281 usbmuxd_log(LL_WARNING, "Attempted to connect to nonexistent device %d", device_id); 287 usbmuxd_log(LL_WARNING, "Attempted to connect to nonexistent device %d", device_id);
282 return -RESULT_BADDEV; 288 return -RESULT_BADDEV;
@@ -359,6 +365,7 @@ static void update_connection(struct mux_connection *conn)
359void device_client_process(int device_id, struct mux_client *client, short events) 365void device_client_process(int device_id, struct mux_client *client, short events)
360{ 366{
361 struct mux_connection *conn = NULL; 367 struct mux_connection *conn = NULL;
368 pthread_mutex_lock(&device_list_mutex);
362 FOREACH(struct mux_device *dev, &device_list) { 369 FOREACH(struct mux_device *dev, &device_list) {
363 if(dev->id == device_id) { 370 if(dev->id == device_id) {
364 FOREACH(struct mux_connection *lconn, &dev->connections) { 371 FOREACH(struct mux_connection *lconn, &dev->connections) {
@@ -370,6 +377,7 @@ void device_client_process(int device_id, struct mux_client *client, short event
370 break; 377 break;
371 } 378 }
372 } ENDFOREACH 379 } ENDFOREACH
380 pthread_mutex_unlock(&device_list_mutex);
373 381
374 if(!conn) { 382 if(!conn) {
375 usbmuxd_log(LL_WARNING, "Could not find connection for device %d client %p", device_id, client); 383 usbmuxd_log(LL_WARNING, "Could not find connection for device %d client %p", device_id, client);
@@ -427,18 +435,22 @@ static void connection_device_input(struct mux_connection *conn, unsigned char *
427 435
428void device_abort_connect(int device_id, struct mux_client *client) 436void device_abort_connect(int device_id, struct mux_client *client)
429{ 437{
438 pthread_mutex_lock(&device_list_mutex);
430 FOREACH(struct mux_device *dev, &device_list) { 439 FOREACH(struct mux_device *dev, &device_list) {
431 if(dev->id == device_id) { 440 if(dev->id == device_id) {
432 FOREACH(struct mux_connection *conn, &dev->connections) { 441 FOREACH(struct mux_connection *conn, &dev->connections) {
433 if(conn->client == client) { 442 if(conn->client == client) {
434 connection_teardown(conn); 443 connection_teardown(conn);
444 pthread_mutex_unlock(&device_list_mutex);
435 return; 445 return;
436 } 446 }
437 } ENDFOREACH 447 } ENDFOREACH
448 pthread_mutex_unlock(&device_list_mutex);
438 usbmuxd_log(LL_WARNING, "Attempted to abort for nonexistent connection for device %d", device_id); 449 usbmuxd_log(LL_WARNING, "Attempted to abort for nonexistent connection for device %d", device_id);
439 return; 450 return;
440 } 451 }
441 } ENDFOREACH 452 } ENDFOREACH
453 pthread_mutex_unlock(&device_list_mutex);
442 usbmuxd_log(LL_WARNING, "Attempted to abort connection for nonexistent device %d", device_id); 454 usbmuxd_log(LL_WARNING, "Attempted to abort connection for nonexistent device %d", device_id);
443} 455}
444 456
@@ -452,7 +464,9 @@ static void device_version_input(struct mux_device *dev, struct version_header *
452 vh->minor = ntohl(vh->minor); 464 vh->minor = ntohl(vh->minor);
453 if(vh->major != 1 || vh->minor != 0) { 465 if(vh->major != 1 || vh->minor != 0) {
454 usbmuxd_log(LL_ERROR, "Device %d has unknown version %d.%d\n", dev->id, vh->major, vh->minor); 466 usbmuxd_log(LL_ERROR, "Device %d has unknown version %d.%d\n", dev->id, vh->major, vh->minor);
467 pthread_mutex_lock(&device_list_mutex);
455 collection_remove(&device_list, dev); 468 collection_remove(&device_list, dev);
469 pthread_mutex_unlock(&device_list_mutex);
456 free(dev); 470 free(dev);
457 return; 471 return;
458 } 472 }
@@ -548,12 +562,14 @@ static void device_tcp_input(struct mux_device *dev, struct tcphdr *th, unsigned
548void device_data_input(struct usb_device *usbdev, unsigned char *buffer, uint32_t length) 562void device_data_input(struct usb_device *usbdev, unsigned char *buffer, uint32_t length)
549{ 563{
550 struct mux_device *dev = NULL; 564 struct mux_device *dev = NULL;
565 pthread_mutex_lock(&device_list_mutex);
551 FOREACH(struct mux_device *tdev, &device_list) { 566 FOREACH(struct mux_device *tdev, &device_list) {
552 if(tdev->usbdev == usbdev) { 567 if(tdev->usbdev == usbdev) {
553 dev = tdev; 568 dev = tdev;
554 break; 569 break;
555 } 570 }
556 } ENDFOREACH 571 } ENDFOREACH
572 pthread_mutex_unlock(&device_list_mutex);
557 if(!dev) { 573 if(!dev) {
558 usbmuxd_log(LL_WARNING, "Cannot find device entry for RX input from USB device %p on location 0x%x", usbdev, usb_get_location(usbdev)); 574 usbmuxd_log(LL_WARNING, "Cannot find device entry for RX input from USB device %p on location 0x%x", usbdev, usb_get_location(usbdev));
559 return; 575 return;
@@ -659,12 +675,15 @@ int device_add(struct usb_device *usbdev)
659 free(dev); 675 free(dev);
660 return res; 676 return res;
661 } 677 }
678 pthread_mutex_lock(&device_list_mutex);
662 collection_add(&device_list, dev); 679 collection_add(&device_list, dev);
680 pthread_mutex_unlock(&device_list_mutex);
663 return 0; 681 return 0;
664} 682}
665 683
666void device_remove(struct usb_device *usbdev) 684void device_remove(struct usb_device *usbdev)
667{ 685{
686 pthread_mutex_lock(&device_list_mutex);
668 FOREACH(struct mux_device *dev, &device_list) { 687 FOREACH(struct mux_device *dev, &device_list) {
669 if(dev->usbdev == usbdev) { 688 if(dev->usbdev == usbdev) {
670 usbmuxd_log(LL_NOTICE, "Removed device %d on location 0x%x", dev->id, usb_get_location(usbdev)); 689 usbmuxd_log(LL_NOTICE, "Removed device %d on location 0x%x", dev->id, usb_get_location(usbdev));
@@ -680,47 +699,57 @@ void device_remove(struct usb_device *usbdev)
680 preflight_device_remove_cb(dev->preflight_cb_data); 699 preflight_device_remove_cb(dev->preflight_cb_data);
681 } 700 }
682 collection_remove(&device_list, dev); 701 collection_remove(&device_list, dev);
702 pthread_mutex_unlock(&device_list_mutex);
683 free(dev->pktbuf); 703 free(dev->pktbuf);
684 free(dev); 704 free(dev);
685 return; 705 return;
686 } 706 }
687 } ENDFOREACH 707 } ENDFOREACH
708 pthread_mutex_unlock(&device_list_mutex);
709
688 usbmuxd_log(LL_WARNING, "Cannot find device entry while removing USB device %p on location 0x%x", usbdev, usb_get_location(usbdev)); 710 usbmuxd_log(LL_WARNING, "Cannot find device entry while removing USB device %p on location 0x%x", usbdev, usb_get_location(usbdev));
689} 711}
690 712
691void device_set_visible(int device_id) 713void device_set_visible(int device_id)
692{ 714{
715 pthread_mutex_lock(&device_list_mutex);
693 FOREACH(struct mux_device *dev, &device_list) { 716 FOREACH(struct mux_device *dev, &device_list) {
694 if(dev->id == device_id) { 717 if(dev->id == device_id) {
695 dev->visible = 1; 718 dev->visible = 1;
696 break; 719 break;
697 } 720 }
698 } ENDFOREACH 721 } ENDFOREACH
722 pthread_mutex_unlock(&device_list_mutex);
699} 723}
700 724
701void device_set_preflight_cb_data(int device_id, void* data) 725void device_set_preflight_cb_data(int device_id, void* data)
702{ 726{
727 pthread_mutex_lock(&device_list_mutex);
703 FOREACH(struct mux_device *dev, &device_list) { 728 FOREACH(struct mux_device *dev, &device_list) {
704 if(dev->id == device_id) { 729 if(dev->id == device_id) {
705 dev->preflight_cb_data = data; 730 dev->preflight_cb_data = data;
706 break; 731 break;
707 } 732 }
708 } ENDFOREACH 733 } ENDFOREACH
734 pthread_mutex_unlock(&device_list_mutex);
709} 735}
710 736
711int device_get_count(int include_hidden) 737int device_get_count(int include_hidden)
712{ 738{
713 int count = 0; 739 int count = 0;
740 pthread_mutex_unlock(&device_list_mutex);
714 FOREACH(struct mux_device *dev, &device_list) { 741 FOREACH(struct mux_device *dev, &device_list) {
715 if((dev->state == MUXDEV_ACTIVE) && (include_hidden || dev->visible)) 742 if((dev->state == MUXDEV_ACTIVE) && (include_hidden || dev->visible))
716 count++; 743 count++;
717 } ENDFOREACH 744 } ENDFOREACH
745 pthread_mutex_unlock(&device_list_mutex);
718 return count; 746 return count;
719} 747}
720 748
721int device_get_list(int include_hidden, struct device_info *p) 749int device_get_list(int include_hidden, struct device_info *p)
722{ 750{
723 int count = 0; 751 int count = 0;
752 pthread_mutex_lock(&device_list_mutex);
724 FOREACH(struct mux_device *dev, &device_list) { 753 FOREACH(struct mux_device *dev, &device_list) {
725 if((dev->state == MUXDEV_ACTIVE) && (include_hidden || dev->visible)) { 754 if((dev->state == MUXDEV_ACTIVE) && (include_hidden || dev->visible)) {
726 p->id = dev->id; 755 p->id = dev->id;
@@ -731,12 +760,14 @@ int device_get_list(int include_hidden, struct device_info *p)
731 p++; 760 p++;
732 } 761 }
733 } ENDFOREACH 762 } ENDFOREACH
763 pthread_mutex_unlock(&device_list_mutex);
734 return count; 764 return count;
735} 765}
736 766
737int device_get_timeout(void) 767int device_get_timeout(void)
738{ 768{
739 uint64_t oldest = (uint64_t)-1LL; 769 uint64_t oldest = (uint64_t)-1LL;
770 pthread_mutex_lock(&device_list_mutex);
740 FOREACH(struct mux_device *dev, &device_list) { 771 FOREACH(struct mux_device *dev, &device_list) {
741 if(dev->state == MUXDEV_ACTIVE) { 772 if(dev->state == MUXDEV_ACTIVE) {
742 FOREACH(struct mux_connection *conn, &dev->connections) { 773 FOREACH(struct mux_connection *conn, &dev->connections) {
@@ -745,6 +776,7 @@ int device_get_timeout(void)
745 } ENDFOREACH 776 } ENDFOREACH
746 } 777 }
747 } ENDFOREACH 778 } ENDFOREACH
779 pthread_mutex_unlock(&device_list_mutex);
748 uint64_t ct = mstime64(); 780 uint64_t ct = mstime64();
749 if((int64_t)oldest == -1LL) 781 if((int64_t)oldest == -1LL)
750 return 100000; //meh 782 return 100000; //meh
@@ -756,6 +788,7 @@ int device_get_timeout(void)
756void device_check_timeouts(void) 788void device_check_timeouts(void)
757{ 789{
758 uint64_t ct = mstime64(); 790 uint64_t ct = mstime64();
791 pthread_mutex_lock(&device_list_mutex);
759 FOREACH(struct mux_device *dev, &device_list) { 792 FOREACH(struct mux_device *dev, &device_list) {
760 if(dev->state == MUXDEV_ACTIVE) { 793 if(dev->state == MUXDEV_ACTIVE) {
761 FOREACH(struct mux_connection *conn, &dev->connections) { 794 FOREACH(struct mux_connection *conn, &dev->connections) {
@@ -771,12 +804,14 @@ void device_check_timeouts(void)
771 } ENDFOREACH 804 } ENDFOREACH
772 } 805 }
773 } ENDFOREACH 806 } ENDFOREACH
807 pthread_mutex_unlock(&device_list_mutex);
774} 808}
775 809
776void device_init(void) 810void device_init(void)
777{ 811{
778 usbmuxd_log(LL_DEBUG, "device_init"); 812 usbmuxd_log(LL_DEBUG, "device_init");
779 collection_init(&device_list); 813 collection_init(&device_list);
814 pthread_mutex_init(&device_list_mutex, NULL);
780 next_device_id = 1; 815 next_device_id = 1;
781} 816}
782 817
@@ -797,6 +832,7 @@ void device_kill_connections(void)
797void device_shutdown(void) 832void device_shutdown(void)
798{ 833{
799 usbmuxd_log(LL_DEBUG, "device_shutdown"); 834 usbmuxd_log(LL_DEBUG, "device_shutdown");
835 pthread_mutex_lock(&device_list_mutex);
800 FOREACH(struct mux_device *dev, &device_list) { 836 FOREACH(struct mux_device *dev, &device_list) {
801 FOREACH(struct mux_connection *conn, &dev->connections) { 837 FOREACH(struct mux_connection *conn, &dev->connections) {
802 connection_teardown(conn); 838 connection_teardown(conn);
@@ -805,5 +841,7 @@ void device_shutdown(void)
805 collection_remove(&device_list, dev); 841 collection_remove(&device_list, dev);
806 free(dev); 842 free(dev);
807 } ENDFOREACH 843 } ENDFOREACH
844 pthread_mutex_unlock(&device_list_mutex);
845 pthread_mutex_destroy(&device_list_mutex);
808 collection_free(&device_list); 846 collection_free(&device_list);
809} 847}