summaryrefslogtreecommitdiff
path: root/src/lib/ecore_con/efl_net_ip_address.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ecore_con/efl_net_ip_address.c')
-rw-r--r--src/lib/ecore_con/efl_net_ip_address.c188
1 files changed, 105 insertions, 83 deletions
diff --git a/src/lib/ecore_con/efl_net_ip_address.c b/src/lib/ecore_con/efl_net_ip_address.c
index 13e14a052d..e2fbb68f06 100644
--- a/src/lib/ecore_con/efl_net_ip_address.c
+++ b/src/lib/ecore_con/efl_net_ip_address.c
@@ -26,6 +26,17 @@ typedef struct _Efl_Net_Ip_Address_Data {
Eina_Slice addr_slice;
} Efl_Net_Ip_Address_Data;
+typedef struct _Efl_Net_Ip_Address_Resolve_Value
+{
+ Eina_Stringshare *request_address; /**< The 'address' argument given to
+ * Efl.Net.Ip_Address.resolve */
+ Eina_Stringshare *canonical_name; /**< The canonical name, if it was requested in
+ * flags */
+ const Eina_Value_Array results; /**< The resolved objects. Do not modify this array but
+ * you can keep reference to elements using efl_ref()
+ * and efl_unref() */
+} Efl_Net_Ip_Address_Resolve_Value;
+
#define MY_CLASS EFL_NET_IP_ADDRESS_CLASS
EOLIAN static Eo *
@@ -60,7 +71,7 @@ _efl_net_ip_address_efl_object_finalize(Eo *o, Efl_Net_Ip_Address_Data *pd)
}
EOLIAN static const char *
-_efl_net_ip_address_string_get(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
+_efl_net_ip_address_string_get(const Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
{
return pd->string;
}
@@ -85,7 +96,7 @@ _efl_net_ip_address_family_set(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd, i
}
EOLIAN static int
-_efl_net_ip_address_family_get(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
+_efl_net_ip_address_family_get(const Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
{
return pd->addr.sa_family;
}
@@ -112,7 +123,7 @@ _efl_net_ip_address_port_set(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd, uin
}
EOLIAN static uint16_t
-_efl_net_ip_address_port_get(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
+_efl_net_ip_address_port_get(const Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
{
const uint16_t *pport;
@@ -167,7 +178,7 @@ _efl_net_ip_address_address_set(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd,
}
EOLIAN static Eina_Slice
-_efl_net_ip_address_address_get(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
+_efl_net_ip_address_address_get(const Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
{
return pd->addr_slice;
}
@@ -197,7 +208,7 @@ _efl_net_ip_address_sockaddr_set(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd,
}
EOLIAN static const void *
-_efl_net_ip_address_sockaddr_get(Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
+_efl_net_ip_address_sockaddr_get(const Eo *o EINA_UNUSED, Efl_Net_Ip_Address_Data *pd)
{
return &pd->addr;
}
@@ -300,7 +311,7 @@ _efl_net_ip_address_create(Eo *cls, void *pd EINA_UNUSED, uint16_t port, const E
else
family = AF_INET;
- return efl_add(cls, NULL,
+ return efl_add_ref(cls, efl_main_loop_get(),
efl_net_ip_address_family_set(efl_added, family),
efl_net_ip_address_port_set(efl_added, port),
efl_net_ip_address_set(efl_added, address));
@@ -314,7 +325,7 @@ _efl_net_ip_address_create_sockaddr(Eo *cls, void *pd EINA_UNUSED, const void *p
EINA_SAFETY_ON_NULL_RETURN_VAL(sockaddr, NULL);
EINA_SAFETY_ON_TRUE_RETURN_VAL((sockaddr->sa_family != AF_INET) && (sockaddr->sa_family != AF_INET6), NULL);
- return efl_add(cls, NULL,
+ return efl_add_ref(cls, efl_main_loop_get(),
efl_net_ip_address_sockaddr_set(efl_added, sockaddr));
}
@@ -357,85 +368,79 @@ _efl_net_ip_address_parse(Eo *cls, void *pd EINA_UNUSED, const char *numeric_add
return NULL;
}
- return efl_add(cls, NULL,
+ return efl_add_ref(cls, efl_main_loop_get(),
efl_net_ip_address_sockaddr_set(efl_added, &ss));
}
typedef struct _Efl_Net_Ip_Address_Resolve_Context {
- Efl_Net_Ip_Address_Resolve_Results *result;
+ Eina_Stringshare *request_address;
Ecore_Thread *thread;
- Efl_Promise *promise;
+ Eina_Promise *promise;
} Efl_Net_Ip_Address_Resolve_Context;
-static void
-_efl_net_ip_address_resolve_results_free(void *data)
+static Eina_Value_Struct_Desc *
+_efl_net_ip_address_resolve_value_desc_get(void)
{
- Efl_Net_Ip_Address_Resolve_Results *r = data;
-
- if (r->results)
- {
- Eina_Array_Iterator it;
- unsigned int i;
- Efl_Net_Ip_Address *o;
-
- EINA_ARRAY_ITER_NEXT(r->results, i, o, it)
- efl_unref(o);
-
- eina_array_free(r->results);
- r->results = NULL;
- }
+ static Eina_Value_Struct_Member struct_members[] = {
+ // no eina_value_type as they are not constant initializers, see below.
+ EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, canonical_name),
+ EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, request_address),
+ EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, results)
+ };
+ static Eina_Value_Struct_Desc struct_desc = {
+ EINA_VALUE_STRUCT_DESC_VERSION,
+ NULL,
+ struct_members,
+ EINA_C_ARRAY_LENGTH(struct_members),
+ sizeof (Efl_Net_Ip_Address_Resolve_Value)
+ };
+ struct_members[0].type = EINA_VALUE_TYPE_STRINGSHARE;
+ struct_members[1].type = EINA_VALUE_TYPE_STRINGSHARE;
+ struct_members[2].type = EINA_VALUE_TYPE_ARRAY;
+ struct_desc.ops = EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH;
- eina_stringshare_replace(&r->canonical_name, NULL);
- eina_stringshare_replace(&r->request_address, NULL);
- free(r);
+ return &struct_desc;
}
static void
-_efl_net_ip_address_resolve_del(void *data, const Efl_Event *event EINA_UNUSED)
+_efl_net_ip_address_resolve_del(void *data,
+ const Eina_Promise *dead_promise EINA_UNUSED)
{
Efl_Net_Ip_Address_Resolve_Context *ctx = data;
ctx->promise = NULL;
+ eina_stringshare_replace(&ctx->request_address, NULL);
+
if (ctx->thread)
{
ecore_thread_cancel(ctx->thread);
ctx->thread = NULL;
}
- if (ctx->result)
- {
- _efl_net_ip_address_resolve_results_free(ctx->result);
- ctx->result = NULL;
- }
-
free(ctx);
}
static inline int
-_efl_net_ip_address_find(const Eina_Array *array, const struct sockaddr *addr)
+_efl_net_ip_address_find(const Eina_Value *array, const struct sockaddr *addr)
{
- Eina_Array_Iterator it;
- unsigned int i;
const Efl_Net_Ip_Address *o;
+ unsigned int i, len;
- if (addr->sa_family == AF_INET6)
+ EINA_VALUE_ARRAY_FOREACH(array, len, i, o)
{
- EINA_ARRAY_ITER_NEXT(array, i, o, it)
+ const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
+
+ if (addr->sa_family == AF_INET6)
{
- const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
if (other->sa_family == AF_INET6)
{
if (memcmp(other, addr, sizeof(struct sockaddr_in6)) == 0)
return (int)i;
}
}
- }
- else
- {
- EINA_ARRAY_ITER_NEXT(array, i, o, it)
+ else
{
- const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
if (other->sa_family == AF_INET)
{
if (memcmp(other, addr, sizeof(struct sockaddr_in)) == 0)
@@ -447,66 +452,89 @@ _efl_net_ip_address_find(const Eina_Array *array, const struct sockaddr *addr)
}
static void
-_efl_net_ip_address_resolve_done(void *data, const char *host, const char *port, const struct addrinfo *hints EINA_UNUSED, struct addrinfo *result, int gai_error)
+_efl_net_ip_address_resolve_done(void *data,
+ const char *host, const char *port,
+ const struct addrinfo *hints EINA_UNUSED,
+ struct addrinfo *result,
+ int gai_error)
{
Efl_Net_Ip_Address_Resolve_Context *ctx = data;
- Efl_Net_Ip_Address_Resolve_Results *r;
+ Eina_Value_Array desc = { 0 };
+ Eina_Value s = EINA_VALUE_EMPTY;
+ Eina_Value r = EINA_VALUE_EMPTY;
+ Eina_Error err = EFL_NET_ERROR_COULDNT_RESOLVE_HOST;
const struct addrinfo *a;
DBG("done resolving '%s' (host='%s', port='%s'): %s",
- ctx->result->request_address, host, port,
+ ctx->request_address, host, port,
gai_error ? gai_strerror(gai_error) : "success");
ctx->thread = NULL;
if (gai_error)
{
- Eina_Error err = EFL_NET_ERROR_COULDNT_RESOLVE_HOST;
-
if (gai_error == EAI_SYSTEM)
err = errno;
- efl_promise_failed_set(ctx->promise, err);
- return;
+ goto on_error;
}
- ctx->result->results = eina_array_new(16);
- if (!ctx->result->results)
- {
- efl_promise_failed_set(ctx->promise, ENOMEM);
- return;
- }
+ err = ENOMEM;
+ if (!eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 1))
+ goto on_error;
+
+ if (!eina_value_struct_setup(&s, _efl_net_ip_address_resolve_value_desc_get()))
+ goto on_error;
- r = ctx->result;
- ctx->result = NULL; /* steal for efl_promise_value_set() */
+ eina_value_struct_set(&s, "request_address", ctx->request_address);
for (a = result; a != NULL; a = a->ai_next)
{
+ Eina_Stringshare *canonical_name = NULL;
Eo *o;
- if (EINA_UNLIKELY((r->canonical_name == NULL) &&
+ eina_value_struct_get(&s, "canonical_name", &canonical_name);
+ if (EINA_UNLIKELY((canonical_name == NULL) &&
(a->ai_canonname != NULL)))
- r->canonical_name = eina_stringshare_add(a->ai_canonname);
+ {
+ canonical_name = eina_stringshare_add(a->ai_canonname);
+ eina_value_struct_set(&s, "canonical_name", canonical_name);
+ eina_stringshare_del(canonical_name);
+ }
/* some addresses get duplicated with different options that we
* do not care, so check for duplicates.
*/
- if (EINA_UNLIKELY(_efl_net_ip_address_find(r->results, a->ai_addr) >= 0))
+ if (EINA_UNLIKELY(_efl_net_ip_address_find(&r, a->ai_addr) >= 0))
continue;
o = efl_net_ip_address_create_sockaddr(EFL_NET_IP_ADDRESS_CLASS, a->ai_addr);
- if (o)
- {
- if (!eina_array_push(r->results, o))
- efl_del(o);
- }
+ if (!o) continue ;
+
+ eina_value_array_append(&r, o);
+ efl_unref(o);
}
freeaddrinfo(result);
- efl_promise_value_set(ctx->promise, r, _efl_net_ip_address_resolve_results_free);
+ if (!eina_value_pget(&r, &desc)) goto on_error;
+ if (!eina_value_struct_pset(&s, "results", &desc)) goto on_error;
+ eina_value_flush(&r);
+
+ eina_promise_resolve(ctx->promise, s);
+
+ eina_stringshare_replace(&ctx->request_address, NULL);
+ free(ctx);
+
+ return ;
+
+ on_error:
+ eina_promise_reject(ctx->promise, err);
+
+ eina_stringshare_replace(&ctx->request_address, NULL);
+ free(ctx);
}
-EOLIAN static Efl_Future *
+EOLIAN static Eina_Future *
_efl_net_ip_address_resolve(Eo *cls EINA_UNUSED, void *pd EINA_UNUSED, const char *address, int family, int flags)
{
Efl_Net_Ip_Address_Resolve_Context *ctx;
@@ -538,29 +566,23 @@ _efl_net_ip_address_resolve(Eo *cls EINA_UNUSED, void *pd EINA_UNUSED, const cha
ctx = calloc(1, sizeof(Efl_Net_Ip_Address_Resolve_Context));
EINA_SAFETY_ON_NULL_GOTO(ctx, error_ctx);
- ctx->result = calloc(1, sizeof(Efl_Net_Ip_Address_Resolve_Results));
- EINA_SAFETY_ON_NULL_GOTO(ctx->result, error_result);
-
- ctx->result->request_address = eina_stringshare_add(address);
- EINA_SAFETY_ON_NULL_GOTO(ctx->result->request_address, error_result_address);
+ ctx->request_address = eina_stringshare_add(address);
+ EINA_SAFETY_ON_NULL_GOTO(ctx->request_address, error_result_address);
ctx->thread = efl_net_ip_resolve_async_new(host, port, &hints, _efl_net_ip_address_resolve_done, ctx);
EINA_SAFETY_ON_NULL_GOTO(ctx->thread, error_thread);
- ctx->promise = efl_add(EFL_PROMISE_CLASS, efl_main_loop_get(),
- efl_event_callback_add(efl_added, EFL_EVENT_DEL, _efl_net_ip_address_resolve_del, ctx));
+ ctx->promise = eina_promise_new(efl_loop_future_scheduler_get(efl_main_loop_get()), _efl_net_ip_address_resolve_del, ctx);
EINA_SAFETY_ON_NULL_GOTO(ctx->promise, error_promise);
free(str);
- return efl_promise_future_get(ctx->promise);
+ return eina_future_new(ctx->promise);
error_promise:
ecore_thread_cancel(ctx->thread);
error_thread:
- eina_stringshare_del(ctx->result->request_address);
+ eina_stringshare_del(ctx->request_address);
error_result_address:
- free(ctx->result);
- error_result:
free(ctx);
error_ctx:
free(str);