summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2016-05-15 09:51:54 +0200
committerSander Vrijders <[email protected]>2016-05-15 09:51:54 +0200
commitbc94dd6436a62bda6bf3ba11a20dbc50f7094e5a (patch)
treeeb5162928789f8c0eed25a8d00a53d2f93d9cb9e
parent1712f5d78567bbad7a0608fb1428be000a83fe4a (diff)
parente79f151adc07538fbb1057442df2c1fe6ac01836 (diff)
downloadouroboros-bc94dd6436a62bda6bf3ba11a20dbc50f7094e5a.tar.gz
ouroboros-bc94dd6436a62bda6bf3ba11a20dbc50f7094e5a.zip
Merged in dstaesse/ouroboros/udp-lockfix (pull request #86)
ipcpd: shim-udp: fixed locking.
-rw-r--r--src/ipcpd/shim-udp/main.c36
-rw-r--r--src/irmd/main.c2
-rw-r--r--src/lib/dev.c17
-rw-r--r--src/lib/shm_ap_rbuff.c22
4 files changed, 42 insertions, 35 deletions
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 917c343b..2d1691aa 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -189,24 +189,19 @@ void shim_ap_fini()
free(_ap_instance);
}
+/* only call this under flows_lock */
static int port_id_to_fd(int port_id)
{
int i;
- rw_lock_rdlock(&_ap_instance->flows_lock);
-
for (i = 0; i < AP_MAX_FLOWS; ++i) {
if (_ap_instance->flows[i].port_id == port_id
&& _ap_instance->flows[i].state != FLOW_NULL) {
- rw_lock_unlock(&_ap_instance->flows_lock);
-
return i;
}
}
- rw_lock_unlock(&_ap_instance->flows_lock);
-
return -1;
}
@@ -275,7 +270,7 @@ struct ipcp_udp_data * ipcp_udp_data_create()
udp_data = malloc(sizeof *udp_data);
if (udp_data == NULL) {
- LOG_DBGF("Failed to allocate.");
+ LOG_ERR("Failed to allocate.");
return NULL;
}
@@ -513,8 +508,12 @@ static void * ipcp_udp_sdu_loop(void * o)
continue;
}
+ rw_lock_rdlock(&_ap_instance->flows_lock);
+
fd = port_id_to_fd(e->port_id);
+ rw_lock_unlock(&_ap_instance->flows_lock);
+
if (fd == -1) {
rw_lock_unlock(&_ap_instance->data_lock);
free(e);
@@ -1054,11 +1053,7 @@ static int ipcp_udp_flow_alloc_resp(int port_id,
int response)
{
struct shm_ap_rbuff * rb;
- int fd = port_id_to_fd(port_id);
- if (fd < 0) {
- LOG_DBGF("Could not find flow with port_id %d.", port_id);
- return 0;
- }
+ int fd = -1;
if (response)
return 0;
@@ -1067,6 +1062,14 @@ static int ipcp_udp_flow_alloc_resp(int port_id,
rw_lock_rdlock(&_ap_instance->flows_lock);
+ fd = port_id_to_fd(port_id);
+ if (fd < 0) {
+ rw_lock_unlock(&_ap_instance->flows_lock);
+
+ LOG_DBGF("Could not find flow with port_id %d.", port_id);
+ return 0;
+ }
+
if (_ap_instance->flows[fd].state != FLOW_PENDING) {
rw_lock_unlock(&_ap_instance->flows_lock);
@@ -1110,16 +1113,19 @@ static int ipcp_udp_flow_alloc_resp(int port_id,
static int ipcp_udp_flow_dealloc(int port_id)
{
- int fd = port_id_to_fd(port_id);
+ int fd = -1;
struct shm_ap_rbuff * rb;
+ rw_lock_wrlock(&_ap_instance->flows_lock);
+
+ fd = port_id_to_fd(port_id);
if (fd < 0) {
+ rw_lock_unlock(&_ap_instance->flows_lock);
+
LOG_DBGF("Could not find flow with port_id %d.", port_id);
return 0;
}
- rw_lock_wrlock(&_ap_instance->flows_lock);
-
_ap_instance->flows[fd].state = FLOW_NULL;
_ap_instance->flows[fd].port_id = 0;
rb = _ap_instance->flows[fd].rb;
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 65c173de..9c515d2a 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1059,6 +1059,8 @@ static int flow_dealloc(int port_id)
list_del(&e->next);
+ bmp_release(instance->port_ids, port_id);
+
pthread_mutex_unlock(&instance->r_lock);
free(e);
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 440f40f9..4b5e56be 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -163,10 +163,8 @@ int ap_reg(char ** difs,
return -EINVAL;
}
- if (_ap_instance == NULL) {
- LOG_DBG("ap_init was not called.");
- return -1;
- }
+ if (_ap_instance == NULL)
+ return -1; /* -ENOTINIT */
msg.code = IRM_MSG_CODE__IRM_AP_REG;
msg.has_pid = true;
@@ -468,11 +466,16 @@ int flow_dealloc(int fd)
msg.code = IRM_MSG_CODE__IRM_FLOW_DEALLOC;
msg.has_port_id = true;
-
- rw_lock_rdlock(&_ap_instance->data_lock);
+ rw_lock_rdlock(&_ap_instance->flows_lock);
msg.port_id = _ap_instance->flows[fd].port_id;
+ rw_lock_unlock(&_ap_instance->flows_lock);
+
+ rw_lock_wrlock(&_ap_instance->data_lock);
+
+ bmp_release(_ap_instance->fds, fd);
+
rw_lock_unlock(&_ap_instance->data_lock);
recv_msg = send_recv_irm_msg(&msg);
@@ -556,7 +559,7 @@ ssize_t flow_write(int fd, void * buf, size_t count)
return 0;
} else {
while (shm_ap_rbuff_write(_ap_instance->flows[fd].rb, &e) < 0)
- LOG_DBGF("Couldn't write to rbuff.");
+ ;
}
rw_lock_unlock(&_ap_instance->data_lock);
diff --git a/src/lib/shm_ap_rbuff.c b/src/lib/shm_ap_rbuff.c
index da6f0e33..0524a96c 100644
--- a/src/lib/shm_ap_rbuff.c
+++ b/src/lib/shm_ap_rbuff.c
@@ -38,7 +38,7 @@
#define SHM_RBUFF_FILE_SIZE (SHM_RBUFF_SIZE * sizeof(struct rb_entry) \
+ 2 * sizeof(size_t) + sizeof(pthread_mutex_t))
-#define shm_rbuff_used(rb)((*rb->ptr_head + SHM_RBUFF_SIZE - *rb->ptr_tail)\
+#define shm_rbuff_used(rb)((*rb->ptr_head + SHM_RBUFF_SIZE - *rb->ptr_tail) \
& (SHM_RBUFF_SIZE - 1))
#define shm_rbuff_free(rb)(shm_rbuff_used(rb) + 1 < SHM_RBUFF_SIZE)
@@ -105,12 +105,10 @@ struct shm_ap_rbuff * shm_ap_rbuff_create()
return NULL;
}
- rb->shm_base = shm_base;
- rb->ptr_head = (size_t *) (rb->shm_base + SHM_RBUFF_SIZE);
- rb->ptr_tail = (size_t *)
- ((uint8_t *) rb->ptr_head + sizeof(size_t));
- rb->shm_mutex = (pthread_mutex_t *)
- ((uint8_t *) rb->ptr_tail + sizeof(size_t));
+ rb->shm_base = shm_base;
+ rb->ptr_head = (size_t *) (rb->shm_base + SHM_RBUFF_SIZE);
+ rb->ptr_tail = rb->ptr_head + 1;
+ rb->shm_mutex = (pthread_mutex_t *) (rb->ptr_tail + 1);
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
@@ -165,12 +163,10 @@ struct shm_ap_rbuff * shm_ap_rbuff_open(pid_t pid)
return NULL;
}
- rb->shm_base = shm_base;
- rb->ptr_head = (size_t *) (rb->shm_base + SHM_RBUFF_SIZE);
- rb->ptr_tail = (size_t *)
- ((uint8_t *) rb->ptr_head + sizeof(size_t));
- rb->shm_mutex = (pthread_mutex_t *)
- ((uint8_t *) rb->ptr_tail + sizeof(size_t));
+ rb->shm_base = shm_base;
+ rb->ptr_head = (size_t *) (rb->shm_base + SHM_RBUFF_SIZE);
+ rb->ptr_tail = rb->ptr_head + 1;
+ rb->shm_mutex = (pthread_mutex_t *) (rb->ptr_tail + 1);
rb->fd = shm_fd;
rb->pid = pid;