--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Eina.h"
+
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
+
+#ifdef CRI
+# undef CRI
+#endif
+#define CRI(...) EINA_LOG_DOM_CRIT(EINA_LOG_DOMAIN_GLOBAL, __VA_ARGS__)
+
+typedef struct pxProxyFactory_ pxProxyFactory;
+typedef struct _Libproxy
+{
+ pxProxyFactory *factory;
+ char **(*px_proxy_factory_get_proxies) (pxProxyFactory *factory, const char *url);
+ void *(*px_proxy_factory_new) (void);
+ void (*px_proxy_factory_free) (pxProxyFactory *);
+ Eina_Module *mod;
+} Libproxy;
+static Libproxy _libproxy = { 0 };
+
+static Eina_Spinlock pending_lock;
+static int pending = 0;
+static int opcount = 0;
+static Eina_List *join_list = NULL;
+
+static Eina_Bool
+init(void)
+{
+ if (!_libproxy.mod)
+ {
+#define LOAD(x) \
+ if (!_libproxy.mod) { \
+ _libproxy.mod = eina_module_new(x); \
+ if (_libproxy.mod) { \
+ if (!eina_module_load(_libproxy.mod)) { \
+ eina_module_free(_libproxy.mod); \
+ _libproxy.mod = NULL; \
+ } \
+ } \
+ }
+#if defined(_WIN32) || defined(__CYGWIN__)
+ LOAD("libproxy-1.dll");
+ LOAD("libproxy.dll");
+#elif defined(__APPLE__) && defined(__MACH__)
+ LOAD("libproxy.1.dylib");
+ LOAD("libproxy.dylib");
+#else
+ LOAD("libproxy.so.1");
+ LOAD("libproxy.so");
+#endif
+#undef LOAD
+ if (!_libproxy.mod)
+ {
+ DBG("Couldn't find libproxy in your system. Continue without it");
+ return EINA_FALSE;
+ }
+
+#define SYM(x) \
+ if ((_libproxy.x = eina_module_symbol_get(_libproxy.mod, #x)) == NULL) { \
+ ERR("libproxy (%s) missing symbol %s", \
+ eina_module_file_get(_libproxy.mod), #x); \
+ eina_module_free(_libproxy.mod); \
+ _libproxy.mod = NULL; \
+ return EINA_FALSE; \
+ }
+
+ SYM(px_proxy_factory_new);
+ SYM(px_proxy_factory_free);
+ SYM(px_proxy_factory_get_proxies);
+#undef SYM
+ DBG("using libproxy=%s", eina_module_file_get(_libproxy.mod));
+ }
+
+ if (!_libproxy.factory)
+ _libproxy.factory = _libproxy.px_proxy_factory_new();
+
+ return !!_libproxy.factory;
+}
+
+static void
+shutdown(void)
+{
+ if (_libproxy.factory)
+ {
+ _libproxy.px_proxy_factory_free(_libproxy.factory);
+ _libproxy.factory = NULL;
+ }
+ if (_libproxy.mod)
+ {
+ eina_module_free(_libproxy.mod);
+ _libproxy.mod = NULL;
+ }
+}
+
+static void *
+proxy_lookup(void *data, Eina_Thread t)
+{
+ char *cmd = data;
+ char **proxies, **itr;
+ const char *p, *url;
+ int id = atoi(cmd + 2);
+ int pending_local, opcount_prev;
+
+ if (id > 0)
+ {
+ for (p = cmd + 2; *p && (*p != ' '); p++);
+ if (*p == ' ')
+ {
+ url = p + 1;
+ proxies = _libproxy.px_proxy_factory_get_proxies
+ (_libproxy.factory, url);
+ if (proxies)
+ {
+ for (itr = proxies; *itr != NULL; itr++)
+ {
+ fprintf(stdout, "P %i P %s\n", id, *itr);
+ free(*itr);
+ }
+ free(proxies);
+ }
+ fprintf(stdout, "P %i E\n", id);
+ fflush(stdout);
+ }
+ }
+ free(cmd);
+
+ eina_spinlock_take(&pending_lock);
+ {
+ pending--;
+ pending_local = pending;
+ opcount_prev = opcount;
+ }
+ eina_spinlock_release(&pending_lock);
+ // if there are no more pending threads doing work - sleep for the
+ // timeout then check if we still are and if so - exit;
+ if (pending_local == 0) sleep(10);
+ eina_spinlock_take(&pending_lock);
+ {
+ Eina_Thread *tt;
+
+ if ((pending == 0) & (opcount == opcount_prev)) exit(0);
+ tt = calloc(1, sizeof(Eina_Thread));
+ if (tt)
+ {
+ *tt = t;
+ join_list = eina_list_append(join_list, tt);
+ }
+ }
+ eina_spinlock_release(&pending_lock);
+ return NULL;
+}
+
+static void
+handle(const char *cmd)
+{
+ // "P 1234 URL" -> Get Proxy, id=1234, url=URL
+ if ((cmd[0] == 'P') && (cmd[1] == ' '))
+ {
+ char *dup = strdup(cmd);
+
+ if (dup)
+ {
+ Eina_Thread t;
+
+ eina_spinlock_take(&pending_lock);
+ {
+ pending++;
+ opcount++;
+ }
+ eina_spinlock_release(&pending_lock);
+ if (!eina_thread_create(&t, EINA_THREAD_BACKGROUND, -1,
+ proxy_lookup, dup))
+ {
+ abort();
+ }
+ }
+ return;
+ }
+}
+
+static void
+clean_threads(void)
+{
+ eina_spinlock_take(&pending_lock);
+ {
+ Eina_Thread *t;
+
+ EINA_LIST_FREE(join_list, t)
+ {
+ eina_thread_join(*t);
+ free(t);
+ }
+ }
+ eina_spinlock_release(&pending_lock);
+}
+
+int
+main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{
+ char inbuf[8192];
+ eina_init();
+ if (init())
+ {
+ eina_spinlock_new(&pending_lock);
+ // 1 command per stdin line
+ while (fgets(inbuf, sizeof(inbuf) - 1, stdin))
+ {
+ // strip off newline and ensure the string is 0 terminated
+ int len = strlen(inbuf);
+ if (len > 0)
+ {
+ if (inbuf[len -1 ] == '\n') inbuf[len - 1] = 0;
+ else inbuf[len] = 0;
+ handle(inbuf);
+ }
+ clean_threads();
+ }
+ eina_spinlock_free(&pending_lock);
+ shutdown();
+ }
+ else
+ {
+ // Failed to init libproxy so report this before exit
+ fprintf(stdout, "F\n");
+ fflush(stdout);
+ pause();
+ }
+ eina_shutdown();
+ return 0;
+}
static int _ecore_con_init_count = 0;
int _ecore_con_log_dom = -1;
-typedef struct pxProxyFactory_ pxProxyFactory;
-typedef struct _Ecore_Con_Libproxy {
- pxProxyFactory *factory;
- char **(*px_proxy_factory_get_proxies)(pxProxyFactory *factory, const char *url);
- void *(*px_proxy_factory_new)(void);
- void (*px_proxy_factory_free)(pxProxyFactory *);
- Eina_Module *mod;
-} Ecore_Con_Libproxy;
-static Ecore_Con_Libproxy _ecore_con_libproxy;
+Eina_Bool _efl_net_proxy_helper_can_do (void);
+int _efl_net_proxy_helper_url_req_send(const char *url);
+char **_efl_net_proxy_helper_url_wait (int id);
+void _efl_net_proxy_helper_init (void);
+void _efl_net_proxy_helper_shutdown (void);
EAPI int
ecore_con_init(void)
goto ecore_con_log_error;
}
+ _efl_net_proxy_helper_init();
+
ecore_con_mempool_init();
ecore_con_legacy_init();
if (--_ecore_con_init_count != 0)
return _ecore_con_init_count;
- if (_ecore_con_libproxy.factory)
- {
- _ecore_con_libproxy.px_proxy_factory_free(_ecore_con_libproxy.factory);
- _ecore_con_libproxy.factory = NULL;
- }
- if (_ecore_con_libproxy.mod)
- {
- eina_module_free(_ecore_con_libproxy.mod);
- _ecore_con_libproxy.mod = NULL;
- }
+ _efl_net_proxy_helper_shutdown();
eina_log_timing(_ecore_con_log_dom,
EINA_LOG_STATE_START,
proxy = d->proxy;
- if ((!proxy) && (_ecore_con_libproxy.factory))
+ if ((!proxy) && _efl_net_proxy_helper_can_do())
{
- /* libproxy is thread-safe but not cancellable. the provided
- * parameter must be a URL with schema, otherwise it won't
- * return anything.
- */
Eina_Stringshare *url;
url = eina_stringshare_printf("%s://%s:%s", d->protocol == IPPROTO_UDP ? "udp" : "tcp", host, port);
return READBUFSIZ;
}
-Eina_Bool
-ecore_con_libproxy_init(void)
-{
- if (!_ecore_con_libproxy.mod)
- {
-#define LOAD(x) \
- if (!_ecore_con_libproxy.mod) { \
- _ecore_con_libproxy.mod = eina_module_new(x); \
- if (_ecore_con_libproxy.mod) { \
- if (!eina_module_load(_ecore_con_libproxy.mod)) { \
- eina_module_free(_ecore_con_libproxy.mod); \
- _ecore_con_libproxy.mod = NULL; \
- } \
- } \
- }
-#if defined(_WIN32) || defined(__CYGWIN__)
- LOAD("libproxy-1.dll");
- LOAD("libproxy.dll");
-#elif defined(__APPLE__) && defined(__MACH__)
- LOAD("libproxy.1.dylib");
- LOAD("libproxy.dylib");
-#else
- LOAD("libproxy.so.1");
- LOAD("libproxy.so");
-#endif
-#undef LOAD
- if (!_ecore_con_libproxy.mod)
- {
- DBG("Couldn't find libproxy in your system. Continue without it");
- return EINA_FALSE;
- }
-
-#define SYM(x) \
- if ((_ecore_con_libproxy.x = eina_module_symbol_get(_ecore_con_libproxy.mod, #x)) == NULL) { \
- ERR("libproxy (%s) missing symbol %s", eina_module_file_get(_ecore_con_libproxy.mod), #x); \
- eina_module_free(_ecore_con_libproxy.mod); \
- _ecore_con_libproxy.mod = NULL; \
- return EINA_FALSE; \
- }
-
- SYM(px_proxy_factory_new);
- SYM(px_proxy_factory_free);
- SYM(px_proxy_factory_get_proxies);
-#undef SYM
- DBG("using libproxy=%s", eina_module_file_get(_ecore_con_libproxy.mod));
- }
-
- if (!_ecore_con_libproxy.factory)
- _ecore_con_libproxy.factory = _ecore_con_libproxy.px_proxy_factory_new();
-
- return !!_ecore_con_libproxy.factory;
-}
-
char **
ecore_con_libproxy_proxies_get(const char *url)
{
- EINA_SAFETY_ON_NULL_RETURN_VAL(_ecore_con_libproxy.px_proxy_factory_get_proxies, NULL);
- return _ecore_con_libproxy.px_proxy_factory_get_proxies(_ecore_con_libproxy.factory, url);
+ int id = _efl_net_proxy_helper_url_req_send(url);
+ if (id < 0) return NULL;
+ return _efl_net_proxy_helper_url_wait(id);
}
void
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef HAVE_EVIL
+# include <Evil.h>
+#endif
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Con.h"
+#include "ecore_con_private.h"
+
+typedef struct {
+ Eina_Thread_Queue *thq;
+ char *str;
+ char **proxies;
+ int id;
+ int busy;
+} Efl_Net_Proxy_Helper_Req;
+
+typedef struct {
+ Eina_Thread_Queue_Msg head;
+ char **proxies;
+} Efl_Net_Proxy_Helper_Thq_Msg;
+
+static Eina_Bool _efl_net_proxy_helper_works = EINA_TRUE;
+static Ecore_Exe *_efl_net_proxy_helper_exe = NULL;
+static Eina_Prefix *_efl_net_proxy_helper_prefix = NULL;
+static Eina_Spinlock _efl_net_proxy_helper_queue_lock;
+static int _efl_net_proxy_helper_req_id = 0;
+static Eina_List *_efl_net_proxy_helper_queue = NULL;
+static Ecore_Event_Handler *_efl_net_proxy_helper_handler_exe_del = NULL;
+static Ecore_Event_Handler *_efl_net_proxy_helper_handler_exe_data = NULL;
+static Eina_Bool _efl_net_proxy_helper_queue_lock_init = EINA_FALSE;
+static int _efl_net_proxy_helper_init_num = 0;
+
+static int locks = 0;
+
+#ifdef _WIN32
+# define HELPER_EXT ".exe"
+#else
+# define HELPER_EXT
+#endif
+
+static void
+_efl_net_proxy_helper_spawn(void)
+{
+ char buf[PATH_MAX];
+ Eina_List *l;
+ Efl_Net_Proxy_Helper_Req *req;
+ static int run_in_tree = -1;
+
+ if (!_efl_net_proxy_helper_works) return;
+ if (_efl_net_proxy_helper_exe) return;
+ if (run_in_tree == -1)
+ {
+ run_in_tree = 0;
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+ if (getuid() == geteuid())
+#endif
+ {
+ if (getenv("EFL_RUN_IN_TREE")) run_in_tree = 1;
+ }
+ }
+ // find binary location path
+ if (run_in_tree == 1)
+ snprintf
+ (buf, sizeof(buf),
+ PACKAGE_BUILD_DIR"/src/bin/ecore_con/utils/efl_net_proxy_helper"HELPER_EXT);
+ else
+ snprintf
+ (buf, sizeof(buf),
+ "%s/ecore_con/utils/"MODULE_ARCH"/efl_net_proxy_helper"HELPER_EXT,
+ eina_prefix_lib_get(_efl_net_proxy_helper_prefix));
+ // run it with stdin/out piped line buffered with events
+ _efl_net_proxy_helper_exe = ecore_exe_pipe_run
+ (buf,
+ ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_TERM_WITH_PARENT |
+ ECORE_EXE_NOT_LEADER, NULL);
+ // resend unhandled requests
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
+ ecore_exe_send(_efl_net_proxy_helper_exe,
+ req->str, strlen(req->str));
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+}
+
+static void
+_efl_net_proxy_helper_kill(void)
+{
+ if (!_efl_net_proxy_helper_exe) return;
+ // don't exit if anything is pending
+ if (_efl_net_proxy_helper_queue) return;
+ ecore_exe_kill(_efl_net_proxy_helper_exe);
+ ecore_exe_free(_efl_net_proxy_helper_exe);
+ _efl_net_proxy_helper_exe = NULL;
+}
+
+static void
+_efl_net_proxy_helper_cancel(void)
+{
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ Efl_Net_Proxy_Helper_Req *req;
+
+ EINA_LIST_FREE(_efl_net_proxy_helper_queue, req)
+ {
+ Efl_Net_Proxy_Helper_Thq_Msg *msg;
+ void *ref;
+
+ msg = eina_thread_queue_send
+ (req->thq, sizeof(Efl_Net_Proxy_Helper_Thq_Msg), &ref);
+ msg->proxies = NULL;
+ eina_thread_queue_send_done(req->thq, ref);
+ if (!req->busy)
+ {
+ free(req->str);
+ ecore_con_libproxy_proxies_free(req->proxies);
+ eina_thread_queue_free(req->thq);
+ free(req);
+ }
+ }
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+}
+
+static void
+_efl_net_proxy_helper_proxy_add(int id, const char *url)
+{
+ Eina_List *l;
+ Efl_Net_Proxy_Helper_Req *req;
+
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
+ {
+ if (req->id == id) break;
+ req = NULL;
+ }
+ if (req)
+ {
+ if (url)
+ {
+ char **proxies = req->proxies;
+ int n = 0;
+
+ if (proxies)
+ {
+ for (n = 0; proxies[n]; n++);
+ }
+ n++;
+ proxies = realloc(proxies, sizeof(char *) * (n + 1));
+ if (proxies)
+ {
+ req->proxies = proxies;
+ proxies[n - 1] = strdup(url);
+ proxies[n] = NULL;
+ }
+ }
+ else
+ {
+ Efl_Net_Proxy_Helper_Thq_Msg *msg;
+ void *ref;
+
+ msg = eina_thread_queue_send
+ (req->thq, sizeof(Efl_Net_Proxy_Helper_Thq_Msg), &ref);
+ msg->proxies = req->proxies;
+ req->proxies = NULL;
+ eina_thread_queue_send_done(req->thq, ref);
+ }
+ }
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+}
+
+static Eina_Bool
+_efl_net_proxy_helper_cb_exe_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *info)
+{
+ Ecore_Exe_Event_Del *event = info;
+
+ if (!_efl_net_proxy_helper_exe) return EINA_TRUE;
+ if (event->exe == _efl_net_proxy_helper_exe)
+ {
+ static double last_respawn = 0.0;
+ double t;
+ Eina_Bool respawn = EINA_FALSE;
+
+ t = ecore_time_get();
+ _efl_net_proxy_helper_exe = NULL;
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ if (_efl_net_proxy_helper_queue)
+ {
+ if ((t - last_respawn) > 5.0) respawn = EINA_TRUE;
+ }
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+ if (respawn)
+ {
+ last_respawn = t;
+ _efl_net_proxy_helper_spawn();
+ }
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_efl_net_proxy_helper_cb_exe_data(void *data EINA_UNUSED, int type EINA_UNUSED, void *info)
+{
+ Ecore_Exe_Event_Data *event = info;
+
+ if (!_efl_net_proxy_helper_exe) return EINA_TRUE;
+ if (event->exe == _efl_net_proxy_helper_exe)
+ {
+ if (event->lines)
+ {
+ int i;
+
+ for (i = 0; event->lines[i].line; i++)
+ {
+ char *line = event->lines[i].line;
+
+ if (line[0] == 'F') // failure
+ {
+ _efl_net_proxy_helper_works = EINA_FALSE;
+ _efl_net_proxy_helper_cancel();
+ _efl_net_proxy_helper_kill();
+ }
+ else if ((line[0] == 'P') && (line[1] == ' ')) // proxy
+ {
+ int id = atoi(line + 2);
+ char *p, *url = NULL;
+
+ for (p = line + 2; *p && (*p != ' '); p++);
+ if ((p[0] == ' ') && (p[1] == 'P') && (p[2] == ' '))
+ url = p + 3;
+ else if ((p[0] == ' ') && (p[1] == 'E'))
+ url = NULL;
+ _efl_net_proxy_helper_proxy_add(id, url);
+ }
+ }
+ }
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+Eina_Bool
+_efl_net_proxy_helper_can_do(void)
+{
+ return _efl_net_proxy_helper_works;
+}
+
+
+static void
+_efl_net_proxy_helper_cb_send_do(void *data)
+{
+ char *str = data;
+ if (!str) return;
+ // spawn exe if needed
+ if (!_efl_net_proxy_helper_exe) _efl_net_proxy_helper_spawn();
+ if (_efl_net_proxy_helper_exe)
+ ecore_exe_send(_efl_net_proxy_helper_exe, str, strlen(str));
+ free(str);
+}
+
+int
+_efl_net_proxy_helper_url_req_send(const char *url)
+{
+ char *buf;
+ int id = -1;
+ Efl_Net_Proxy_Helper_Req *req;
+
+ if (!_efl_net_proxy_helper_works) return -1;
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ // new id - just an int that eventually loops.
+ _efl_net_proxy_helper_req_id++;
+ if (_efl_net_proxy_helper_req_id >= ((1 << 30) - 1))
+ _efl_net_proxy_helper_req_id = 1;
+ id = _efl_net_proxy_helper_req_id;
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+ // create request to quque up to look up responses for
+ req = calloc(1, sizeof(Efl_Net_Proxy_Helper_Req));
+ if (!req) return -1;
+ req->id = id;
+ req->thq = eina_thread_queue_new();
+ if (!req->thq)
+ {
+ free(req);
+ return -1;
+ }
+ buf = alloca(strlen(url) + 256);
+ sprintf(buf, "P %i %s\n", req->id, url);
+ req->str = strdup(buf);
+ if (!req->str)
+ {
+ eina_thread_queue_free(req->thq);
+ free(req);
+ return -1;
+ }
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ _efl_net_proxy_helper_queue =
+ eina_list_append(_efl_net_proxy_helper_queue, req);
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+ // actually send the req now i'ts queued
+ ecore_main_loop_thread_safe_call_async
+ (_efl_net_proxy_helper_cb_send_do, strdup(buf));
+ return id;
+}
+
+char **
+_efl_net_proxy_helper_url_wait(int id)
+{
+ Eina_List *l;
+ Efl_Net_Proxy_Helper_Req *req;
+ Efl_Net_Proxy_Helper_Thq_Msg *msg;
+ void *ref;
+ char **ret = NULL;
+
+ if (id < 0) return NULL;
+ if (!_efl_net_proxy_helper_exe) return NULL;
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ EINA_LIST_FOREACH(_efl_net_proxy_helper_queue, l, req)
+ {
+ if (req->id == id) break;
+ req = NULL;
+ }
+ if (!req) goto end;
+ req->busy++;
+ locks--;
+ }
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+
+ msg = eina_thread_queue_wait(req->thq, &ref);
+ ret = msg->proxies;
+ msg->proxies = NULL;
+ eina_thread_queue_wait_done(req->thq, ref);
+
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ {
+ locks++;
+ free(req->str);
+ ecore_con_libproxy_proxies_free(req->proxies);
+ eina_thread_queue_free(req->thq);
+ _efl_net_proxy_helper_queue =
+ eina_list_remove(_efl_net_proxy_helper_queue, req);
+ free(req);
+ }
+end:
+ locks--;
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+ return ret;
+}
+
+void
+_efl_net_proxy_helper_init(void)
+{
+ _efl_net_proxy_helper_init_num++;
+ if (_efl_net_proxy_helper_init_num > 1) return;
+ if (_efl_net_proxy_helper_prefix) return;
+ _efl_net_proxy_helper_prefix = eina_prefix_new
+ (NULL, ecore_con_init, "ECORE", "ecore", "checkme",
+ PACKAGE_BIN_DIR, PACKAGE_LIB_DIR, PACKAGE_DATA_DIR, PACKAGE_DATA_DIR);
+ if (!_efl_net_proxy_helper_queue_lock_init)
+ {
+ eina_spinlock_new(&_efl_net_proxy_helper_queue_lock);
+ _efl_net_proxy_helper_queue_lock_init = EINA_TRUE;
+ }
+ _efl_net_proxy_helper_handler_exe_del =
+ ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
+ _efl_net_proxy_helper_cb_exe_del, NULL);
+ _efl_net_proxy_helper_handler_exe_data =
+ ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
+ _efl_net_proxy_helper_cb_exe_data, NULL);
+}
+
+void
+_efl_net_proxy_helper_shutdown(void)
+{
+ _efl_net_proxy_helper_init_num--;
+ if (_efl_net_proxy_helper_init_num > 0) return;
+ if (!_efl_net_proxy_helper_prefix) return;
+ if (_efl_net_proxy_helper_exe)
+ {
+ _efl_net_proxy_helper_cancel();
+ _efl_net_proxy_helper_kill();
+ }
+ eina_spinlock_take(&_efl_net_proxy_helper_queue_lock);
+ eina_spinlock_release(&_efl_net_proxy_helper_queue_lock);
+ eina_prefix_free(_efl_net_proxy_helper_prefix);
+ _efl_net_proxy_helper_prefix = NULL;
+ ecore_event_handler_del(_efl_net_proxy_helper_handler_exe_del);
+ _efl_net_proxy_helper_handler_exe_del = NULL;
+ ecore_event_handler_del(_efl_net_proxy_helper_handler_exe_data);
+ _efl_net_proxy_helper_handler_exe_data = NULL;
+}