summaryrefslogtreecommitdiff
path: root/src/lib/ecore_con/efl_net_server_unix.c
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-17 22:23:25 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-18 00:14:58 +0000
commit28aa1a65b695362d2ae8f5caf905f6d3c0fd663e (patch)
tree7c042f701c5cfff17587588e3e15c6b157408a9f /src/lib/ecore_con/efl_net_server_unix.c
parent444f7eed01a23e0cc3c20cd2e6a201cc684b6108 (diff)
ecore_con - freebsd bind blocking workaround
this is to try do a workaround a hard to reproduce blocking bind on some freebsd systems (i can't repro it on my fbsd vm), so try use file locks as an extra barrier and hope they do the right thing without other mysterious problems. @fix
Diffstat (limited to '')
-rw-r--r--src/lib/ecore_con/efl_net_server_unix.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/src/lib/ecore_con/efl_net_server_unix.c b/src/lib/ecore_con/efl_net_server_unix.c
index ed8735fb0b..226d557c29 100644
--- a/src/lib/ecore_con/efl_net_server_unix.c
+++ b/src/lib/ecore_con/efl_net_server_unix.c
@@ -18,6 +18,26 @@
18#include <sys/un.h> 18#include <sys/un.h>
19#endif 19#endif
20 20
21// BSD workaround - unable to reproduce.... but we seem to
22// get a blocking bind here if 2 processes fight over the same
23// socket where one of them loses out by sitting here and
24// blockign forever - as i can't reproduce in the freebsd vm
25// i have, so i'm limited in what to do so this is a
26// workaround to try mitigate this
27#if defined (__FreeBSD__)
28# define BIND_HANG_WORKAROUND 1
29#else
30// only need on freebsd
31//# define BIND_HANG_WORKAROUND 1
32#endif
33
34#ifdef BIND_HANG_WORKAROUND
35# include <sys/file.h>
36# include <sys/types.h>
37# include <sys/stat.h>
38# include <fcntl.h>
39#endif
40
21/* no include EVIL as it's not supposed to be compiled on Windows */ 41/* no include EVIL as it's not supposed to be compiled on Windows */
22 42
23#define MY_CLASS EFL_NET_SERVER_UNIX_CLASS 43#define MY_CLASS EFL_NET_SERVER_UNIX_CLASS
@@ -29,6 +49,52 @@ typedef struct _Efl_Net_Server_Unix_Data
29 Eina_Bool unlink_before_bind; 49 Eina_Bool unlink_before_bind;
30} Efl_Net_Server_Unix_Data; 50} Efl_Net_Server_Unix_Data;
31 51
52#ifdef BIND_HANG_WORKAROUND
53static Eina_Error
54_efl_net_server_unix_bind_hang_lock_workaround(const char *address, Eina_Bool lock)
55{
56 size_t addrlen;
57 char *lockfile;
58 int lockfile_fd, ret;
59 Eina_Error err = 0;
60
61 if (strncmp(address, "abstract:", strlen("abstract:")) == 0) return err;
62
63 addrlen = strlen(address);
64 lockfile = malloc(addrlen + 1 + 5);
65 if (!lockfile) return err;
66
67 strcpy(lockfile, address);
68 strncpy(lockfile + addrlen, ".lock", 6);
69#ifdef HAVE_OPEN_CLOEXEC
70 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC,
71 S_IRUSR | S_IWUSR);
72 if (lockfile_fd < 0) return err;
73#else
74 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC,
75 S_IRUSR | S_IWUSR);
76 if (lockfile_fd < 0) return err;
77 eina_file_close_on_exec(lockfile_fd, EINA_TRUE);
78#endif
79
80 errno = 0;
81 if (lock)
82 {
83 ret = flock(lockfile_fd, LOCK_EX | LOCK_NB);
84 if ((ret != 0) && (errno == EWOULDBLOCK))
85 err = EADDRINUSE;
86 }
87 else
88 {
89 flock(lockfile_fd, LOCK_UN | LOCK_NB);
90 unlink(lockfile);
91 }
92 close(lockfile_fd);
93 free(lockfile);
94 return err;
95}
96#endif
97
32EOLIAN static void 98EOLIAN static void
33_efl_net_server_unix_efl_object_destructor(Eo *o, Efl_Net_Server_Unix_Data *pd EINA_UNUSED) 99_efl_net_server_unix_efl_object_destructor(Eo *o, Efl_Net_Server_Unix_Data *pd EINA_UNUSED)
34{ 100{
@@ -38,7 +104,12 @@ _efl_net_server_unix_efl_object_destructor(Eo *o, Efl_Net_Server_Unix_Data *pd E
38 { 104 {
39 const char *address = efl_net_server_address_get(o); 105 const char *address = efl_net_server_address_get(o);
40 if ((address) && (strncmp(address, "abstract:", strlen("abstract:")) != 0)) 106 if ((address) && (strncmp(address, "abstract:", strlen("abstract:")) != 0))
41 unlink(address); 107 {
108 unlink(address);
109#ifdef BIND_HANG_WORKAROUND
110 _efl_net_server_unix_bind_hang_lock_workaround(address, EINA_FALSE);
111#endif
112 }
42 } 113 }
43 114
44 efl_destructor(efl_super(o, MY_CLASS)); 115 efl_destructor(efl_super(o, MY_CLASS));
@@ -101,6 +172,10 @@ _efl_net_server_unix_bind(Eo *o, Efl_Net_Server_Unix_Data *pd)
101 unlink(addr.sun_path); 172 unlink(addr.sun_path);
102 } 173 }
103 174
175#ifdef BIND_HANG_WORKAROUND
176 if (_efl_net_server_unix_bind_hang_lock_workaround(address, EINA_TRUE))
177 goto error;
178#endif
104 r = bind(fd, (struct sockaddr *)&addr, addrlen); 179 r = bind(fd, (struct sockaddr *)&addr, addrlen);
105 if (r != 0) 180 if (r != 0)
106 { 181 {