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-27 20:03:13 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-27 20:03:13 +0000
commit9e378b52e5217c609a472b070592aff91edb4126 (patch)
tree99dab6daba0195c1560f0b7554da38323dbd42d3 /src/lib/ecore_con/efl_net_server_unix.c
parent5d982dd985c6ed58e71ae1132d247cc5b62c522b (diff)
ecore_con - try an extended bsd workaround by keeping lock open
so keep lock file open for whole duration the socket is bound because bsd seesm to not do this right... :( (2 things can call bind() on the same socket with 1 of them block forever).
Diffstat (limited to '')
-rw-r--r--src/lib/ecore_con/efl_net_server_unix.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/src/lib/ecore_con/efl_net_server_unix.c b/src/lib/ecore_con/efl_net_server_unix.c
index 226d557c29..206845b308 100644
--- a/src/lib/ecore_con/efl_net_server_unix.c
+++ b/src/lib/ecore_con/efl_net_server_unix.c
@@ -45,53 +45,63 @@
45typedef struct _Efl_Net_Server_Unix_Data 45typedef struct _Efl_Net_Server_Unix_Data
46{ 46{
47 unsigned int leading_directories_create_mode; 47 unsigned int leading_directories_create_mode;
48 Eina_Bool leading_directories_create; 48#ifdef BIND_HANG_WORKAROUND
49 Eina_Bool unlink_before_bind; 49 int lock_fd;
50 Eina_Bool have_lock_fd : 1;
51#endif
52 Eina_Bool leading_directories_create : 1;
53 Eina_Bool unlink_before_bind : 1;
50} Efl_Net_Server_Unix_Data; 54} Efl_Net_Server_Unix_Data;
51 55
52#ifdef BIND_HANG_WORKAROUND 56#ifdef BIND_HANG_WORKAROUND
53static Eina_Error 57static int
54_efl_net_server_unix_bind_hang_lock_workaround(const char *address, Eina_Bool lock) 58_efl_net_server_unix_bind_hang_lock_workaround(const char *address, Eina_Bool lock, int lockfile_fd)
55{ 59{
56 size_t addrlen; 60 size_t addrlen;
57 char *lockfile; 61 char *lockfile;
58 int lockfile_fd, ret; 62 int ret;
59 Eina_Error err = 0;
60 63
61 if (strncmp(address, "abstract:", strlen("abstract:")) == 0) return err; 64 if (strncmp(address, "abstract:", strlen("abstract:")) == 0) return -1;
62 65
63 addrlen = strlen(address); 66 addrlen = strlen(address);
64 lockfile = malloc(addrlen + 1 + 5); 67 lockfile = malloc(addrlen + 1 + 5);
65 if (!lockfile) return err; 68 if (!lockfile) return -1;
66 69
67 strcpy(lockfile, address); 70 strcpy(lockfile, address);
68 strncpy(lockfile + addrlen, ".lock", 6); 71 strncpy(lockfile + addrlen, ".lock", 6);
72 if (lock)
73 {
69#ifdef HAVE_OPEN_CLOEXEC 74#ifdef HAVE_OPEN_CLOEXEC
70 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 75 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC,
71 S_IRUSR | S_IWUSR); 76 S_IRUSR | S_IWUSR);
72 if (lockfile_fd < 0) return err; 77 if (lockfile_fd < 0) return -1;
73#else 78#else
74 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC, 79 lockfile_fd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC,
75 S_IRUSR | S_IWUSR); 80 S_IRUSR | S_IWUSR);
76 if (lockfile_fd < 0) return err; 81 if (lockfile_fd < 0) return -1;
77 eina_file_close_on_exec(lockfile_fd, EINA_TRUE); 82 eina_file_close_on_exec(lockfile_fd, EINA_TRUE);
78#endif 83#endif
84 }
79 85
80 errno = 0; 86 errno = 0;
81 if (lock) 87 if (lock)
82 { 88 {
83 ret = flock(lockfile_fd, LOCK_EX | LOCK_NB); 89 ret = flock(lockfile_fd, LOCK_EX | LOCK_NB);
84 if ((ret != 0) && (errno == EWOULDBLOCK)) 90 if ((ret != 0) && (errno == EWOULDBLOCK))
85 err = EADDRINUSE; 91 {
92 close(lockfile_fd);
93 lockfile_fd = -1;
94 }
86 } 95 }
87 else 96 else
88 { 97 {
89 flock(lockfile_fd, LOCK_UN | LOCK_NB); 98 flock(lockfile_fd, LOCK_UN | LOCK_NB);
90 unlink(lockfile); 99 unlink(lockfile);
100 close(lockfile_fd);
101 lockfile_fd = -1;
91 } 102 }
92 close(lockfile_fd);
93 free(lockfile); 103 free(lockfile);
94 return err; 104 return lockfile_fd;
95} 105}
96#endif 106#endif
97 107
@@ -107,7 +117,13 @@ _efl_net_server_unix_efl_object_destructor(Eo *o, Efl_Net_Server_Unix_Data *pd E
107 { 117 {
108 unlink(address); 118 unlink(address);
109#ifdef BIND_HANG_WORKAROUND 119#ifdef BIND_HANG_WORKAROUND
110 _efl_net_server_unix_bind_hang_lock_workaround(address, EINA_FALSE); 120 if ((pd->have_lock_fd) && (pd->lock_fd >= 0))
121 {
122 _efl_net_server_unix_bind_hang_lock_workaround
123 (address, EINA_FALSE, pd->lock_fd);
124 pd->lock_fd = -1;
125 pd->have_lock_fd = EINA_FALSE;
126 }
111#endif 127#endif
112 } 128 }
113 } 129 }
@@ -173,8 +189,14 @@ _efl_net_server_unix_bind(Eo *o, Efl_Net_Server_Unix_Data *pd)
173 } 189 }
174 190
175#ifdef BIND_HANG_WORKAROUND 191#ifdef BIND_HANG_WORKAROUND
176 if (_efl_net_server_unix_bind_hang_lock_workaround(address, EINA_TRUE)) 192 pd->lock_fd = _efl_net_server_unix_bind_hang_lock_workaround
177 goto error; 193 (address, EINA_TRUE, -1);
194 if (pd->lock_fd < 0)
195 {
196 err = EADDRINUSE;
197 goto error;
198 }
199 pd->have_lock_fd = EINA_TRUE;
178#endif 200#endif
179 r = bind(fd, (struct sockaddr *)&addr, addrlen); 201 r = bind(fd, (struct sockaddr *)&addr, addrlen);
180 if (r != 0) 202 if (r != 0)