summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
authordimitri staessens <dimitri.staessens@intec.ugent.be>2016-10-15 19:30:27 +0200
committerdimitri staessens <dimitri.staessens@intec.ugent.be>2016-10-15 19:42:52 +0200
commitb8b05e3b1980146ab8acb40cbe77e0271634c688 (patch)
tree74cc756e3dc9dbb1a694db0ff108f041a9de1152 /src/ipcpd
parentb936e8c62a25c8fae62244ce29d6403ee4aac6ab (diff)
downloadouroboros-b8b05e3b1980146ab8acb40cbe77e0271634c688.tar.gz
ouroboros-b8b05e3b1980146ab8acb40cbe77e0271634c688.zip
lib: Stabilize fast flow deallocation over local IPCP
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/local/main.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 7d23c08d..b8b3335c 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -24,6 +24,7 @@
#include "ipcp.h"
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
+#include <ouroboros/select.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/local-dev.h>
#define OUROBOROS_PREFIX "ipcpd/local"
@@ -66,8 +67,10 @@ void local_data_fini()
static void * ipcp_local_sdu_loop(void * o)
{
while (true) {
- struct rb_entry e;
- int fd = local_flow_read(&e);
+ int fd;
+ struct rb_entry * e;
+
+ fd = flow_select(NULL, NULL);
pthread_rwlock_rdlock(&ipcpi.state_lock);
@@ -77,13 +80,18 @@ static void * ipcp_local_sdu_loop(void * o)
}
pthread_rwlock_rdlock(&local_data.lock);
+
+ e = local_flow_read(fd);
+
fd = local_data.in_out[fd];
- pthread_rwlock_unlock(&local_data.lock);
if (fd != -1)
- local_flow_write(fd, &e);
+ local_flow_write(fd, e);
+ pthread_rwlock_unlock(&local_data.lock);
pthread_rwlock_unlock(&ipcpi.state_lock);
+
+ free(e);
}
return (void *) 1;
@@ -209,8 +217,6 @@ static int ipcp_local_flow_alloc_resp(int fd, int response)
int out_fd = -1;
int ret = -1;
- LOG_DBG("Received response for fd %d: %d.", fd, response);
-
if (response)
return 0;
@@ -235,25 +241,22 @@ static int ipcp_local_flow_alloc_resp(int fd, int response)
static int ipcp_local_flow_dealloc(int fd)
{
- int out_fd = -1;
+ struct timespec t = {0, 10000};
- pthread_rwlock_rdlock(&ipcpi.state_lock);
- pthread_rwlock_wrlock(&local_data.lock);
+ if (fd < 0)
+ return -EINVAL;
- out_fd = local_data.in_out[fd];
+ while (flow_dealloc(fd) == -EBUSY)
+ nanosleep(&t, NULL);
- if (out_fd != -1) {
- local_data.in_out[out_fd] = -1;
- flow_dealloc(out_fd);
- }
+ pthread_rwlock_rdlock(&ipcpi.state_lock);
+ pthread_rwlock_wrlock(&local_data.lock);
local_data.in_out[fd] = -1;
pthread_rwlock_unlock(&local_data.lock);
pthread_rwlock_unlock(&ipcpi.state_lock);
- flow_dealloc(fd);
-
LOG_INFO("Flow with fd %d deallocated.", fd);
return 0;