summaryrefslogtreecommitdiff
path: root/src/lib/ecore_con
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2018-04-27 16:20:47 -0700
committerCedric BAIL <cedric@osg.samsung.com>2018-05-01 10:39:01 -0700
commitec44120e93fac0c933b99eb1b221c8389299930a (patch)
tree9e289f93fcf4608292aa2934dd2f2ee3a89f9b35 /src/lib/ecore_con
parentb1883c7989355e95cd4c826d3c7ecdbbbd257d77 (diff)
ecore_con: migrate efl_net_ip_address_resolve to use Eina_Future.
Diffstat (limited to 'src/lib/ecore_con')
-rw-r--r--src/lib/ecore_con/efl_net_ip_address.c172
-rw-r--r--src/lib/ecore_con/efl_net_ip_address.eo2
2 files changed, 98 insertions, 76 deletions
diff --git a/src/lib/ecore_con/efl_net_ip_address.c b/src/lib/ecore_con/efl_net_ip_address.c
index 802cd206a9..097d233db2 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 {
26 Eina_Slice addr_slice; 26 Eina_Slice addr_slice;
27} Efl_Net_Ip_Address_Data; 27} Efl_Net_Ip_Address_Data;
28 28
29typedef struct _Efl_Net_Ip_Address_Resolve_Value
30{
31 Eina_Stringshare *request_address; /**< The 'address' argument given to
32 * Efl.Net.Ip_Address.resolve */
33 Eina_Stringshare *canonical_name; /**< The canonical name, if it was requested in
34 * flags */
35 const Eina_Value_Array results; /**< The resolved objects. Do not modify this array but
36 * you can keep reference to elements using efl_ref()
37 * and efl_unref() */
38} Efl_Net_Ip_Address_Resolve_Value;
39
29#define MY_CLASS EFL_NET_IP_ADDRESS_CLASS 40#define MY_CLASS EFL_NET_IP_ADDRESS_CLASS
30 41
31EOLIAN static Eo * 42EOLIAN static Eo *
@@ -362,80 +373,74 @@ _efl_net_ip_address_parse(Eo *cls, void *pd EINA_UNUSED, const char *numeric_add
362} 373}
363 374
364typedef struct _Efl_Net_Ip_Address_Resolve_Context { 375typedef struct _Efl_Net_Ip_Address_Resolve_Context {
365 Efl_Net_Ip_Address_Resolve_Results *result; 376 Eina_Stringshare *request_address;
366 Ecore_Thread *thread; 377 Ecore_Thread *thread;
367 Efl_Promise *promise; 378 Eina_Promise *promise;
368} Efl_Net_Ip_Address_Resolve_Context; 379} Efl_Net_Ip_Address_Resolve_Context;
369 380
370static void 381static Eina_Value_Struct_Desc *
371_efl_net_ip_address_resolve_results_free(void *data) 382_efl_net_ip_address_resolve_value_desc_get(void)
372{ 383{
373 Efl_Net_Ip_Address_Resolve_Results *r = data; 384 static Eina_Value_Struct_Member struct_members[] = {
374 385 // no eina_value_type as they are not constant initializers, see below.
375 if (r->results) 386 EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, canonical_name),
376 { 387 EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, request_address),
377 Eina_Array_Iterator it; 388 EINA_VALUE_STRUCT_MEMBER(NULL, Efl_Net_Ip_Address_Resolve_Value, results)
378 unsigned int i; 389 };
379 Efl_Net_Ip_Address *o; 390 static Eina_Value_Struct_Desc struct_desc = {
380 391 EINA_VALUE_STRUCT_DESC_VERSION,
381 EINA_ARRAY_ITER_NEXT(r->results, i, o, it) 392 NULL,
382 efl_unref(o); 393 struct_members,
383 394 EINA_C_ARRAY_LENGTH(struct_members),
384 eina_array_free(r->results); 395 sizeof (Efl_Net_Ip_Address_Resolve_Value)
385 r->results = NULL; 396 };
386 } 397 struct_members[0].type = EINA_VALUE_TYPE_STRINGSHARE;
398 struct_members[1].type = EINA_VALUE_TYPE_STRINGSHARE;
399 struct_members[2].type = EINA_VALUE_TYPE_ARRAY;
400 struct_desc.ops = EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH;
387 401
388 eina_stringshare_replace(&r->canonical_name, NULL); 402 return &struct_desc;
389 eina_stringshare_replace(&r->request_address, NULL);
390 free(r);
391} 403}
392 404
393static void 405static void
394_efl_net_ip_address_resolve_del(void *data, const Efl_Event *event EINA_UNUSED) 406_efl_net_ip_address_resolve_del(void *data,
407 const Eina_Promise *dead_promise EINA_UNUSED)
395{ 408{
396 Efl_Net_Ip_Address_Resolve_Context *ctx = data; 409 Efl_Net_Ip_Address_Resolve_Context *ctx = data;
397 410
398 ctx->promise = NULL; 411 ctx->promise = NULL;
399 412
413 eina_stringshare_replace(&ctx->request_address, NULL);
414
400 if (ctx->thread) 415 if (ctx->thread)
401 { 416 {
402 ecore_thread_cancel(ctx->thread); 417 ecore_thread_cancel(ctx->thread);
403 ctx->thread = NULL; 418 ctx->thread = NULL;
404 } 419 }
405 420
406 if (ctx->result)
407 {
408 _efl_net_ip_address_resolve_results_free(ctx->result);
409 ctx->result = NULL;
410 }
411
412 free(ctx); 421 free(ctx);
413} 422}
414 423
415static inline int 424static inline int
416_efl_net_ip_address_find(const Eina_Array *array, const struct sockaddr *addr) 425_efl_net_ip_address_find(const Eina_Value *array, const struct sockaddr *addr)
417{ 426{
418 Eina_Array_Iterator it;
419 unsigned int i;
420 const Efl_Net_Ip_Address *o; 427 const Efl_Net_Ip_Address *o;
428 unsigned int i, len;
421 429
422 if (addr->sa_family == AF_INET6) 430 EINA_VALUE_ARRAY_FOREACH(array, len, i, o)
423 { 431 {
424 EINA_ARRAY_ITER_NEXT(array, i, o, it) 432 const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
433
434 if (addr->sa_family == AF_INET6)
425 { 435 {
426 const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
427 if (other->sa_family == AF_INET6) 436 if (other->sa_family == AF_INET6)
428 { 437 {
429 if (memcmp(other, addr, sizeof(struct sockaddr_in6)) == 0) 438 if (memcmp(other, addr, sizeof(struct sockaddr_in6)) == 0)
430 return (int)i; 439 return (int)i;
431 } 440 }
432 } 441 }
433 } 442 else
434 else
435 {
436 EINA_ARRAY_ITER_NEXT(array, i, o, it)
437 { 443 {
438 const struct sockaddr *other = efl_net_ip_address_sockaddr_get(o);
439 if (other->sa_family == AF_INET) 444 if (other->sa_family == AF_INET)
440 { 445 {
441 if (memcmp(other, addr, sizeof(struct sockaddr_in)) == 0) 446 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)
447} 452}
448 453
449static void 454static void
450_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) 455_efl_net_ip_address_resolve_done(void *data,
456 const char *host, const char *port,
457 const struct addrinfo *hints EINA_UNUSED,
458 struct addrinfo *result,
459 int gai_error)
451{ 460{
452 Efl_Net_Ip_Address_Resolve_Context *ctx = data; 461 Efl_Net_Ip_Address_Resolve_Context *ctx = data;
453 Efl_Net_Ip_Address_Resolve_Results *r; 462 Eina_Value_Array desc = { 0 };
463 Eina_Value s = EINA_VALUE_EMPTY;
464 Eina_Value r = EINA_VALUE_EMPTY;
465 Eina_Error err = EFL_NET_ERROR_COULDNT_RESOLVE_HOST;
454 const struct addrinfo *a; 466 const struct addrinfo *a;
455 467
456 DBG("done resolving '%s' (host='%s', port='%s'): %s", 468 DBG("done resolving '%s' (host='%s', port='%s'): %s",
457 ctx->result->request_address, host, port, 469 ctx->request_address, host, port,
458 gai_error ? gai_strerror(gai_error) : "success"); 470 gai_error ? gai_strerror(gai_error) : "success");
459 471
460 ctx->thread = NULL; 472 ctx->thread = NULL;
461 473
462 if (gai_error) 474 if (gai_error)
463 { 475 {
464 Eina_Error err = EFL_NET_ERROR_COULDNT_RESOLVE_HOST;
465
466 if (gai_error == EAI_SYSTEM) 476 if (gai_error == EAI_SYSTEM)
467 err = errno; 477 err = errno;
468 478
469 efl_promise_failed_set(ctx->promise, err); 479 goto on_error;
470 return;
471 } 480 }
472 481
473 ctx->result->results = eina_array_new(16); 482 err = ENOMEM;
474 if (!ctx->result->results) 483 if (!eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 1))
475 { 484 goto on_error;
476 efl_promise_failed_set(ctx->promise, ENOMEM); 485
477 return; 486 if (!eina_value_struct_setup(&s, _efl_net_ip_address_resolve_value_desc_get()))
478 } 487 goto on_error;
479 488
480 r = ctx->result; 489 eina_value_struct_set(&s, "request_address", ctx->request_address);
481 ctx->result = NULL; /* steal for efl_promise_value_set() */
482 490
483 for (a = result; a != NULL; a = a->ai_next) 491 for (a = result; a != NULL; a = a->ai_next)
484 { 492 {
493 Eina_Stringshare *canonical_name = NULL;
485 Eo *o; 494 Eo *o;
486 495
487 if (EINA_UNLIKELY((r->canonical_name == NULL) && 496 eina_value_struct_get(&s, "canonical_name", &canonical_name);
497 if (EINA_UNLIKELY((canonical_name == NULL) &&
488 (a->ai_canonname != NULL))) 498 (a->ai_canonname != NULL)))
489 r->canonical_name = eina_stringshare_add(a->ai_canonname); 499 {
500 canonical_name = eina_stringshare_add(a->ai_canonname);
501 eina_value_struct_set(&s, "canonical_name", canonical_name);
502 eina_stringshare_del(canonical_name);
503 }
490 504
491 /* some addresses get duplicated with different options that we 505 /* some addresses get duplicated with different options that we
492 * do not care, so check for duplicates. 506 * do not care, so check for duplicates.
493 */ 507 */
494 if (EINA_UNLIKELY(_efl_net_ip_address_find(r->results, a->ai_addr) >= 0)) 508 if (EINA_UNLIKELY(_efl_net_ip_address_find(&r, a->ai_addr) >= 0))
495 continue; 509 continue;
496 510
497 o = efl_net_ip_address_create_sockaddr(EFL_NET_IP_ADDRESS_CLASS, a->ai_addr); 511 o = efl_net_ip_address_create_sockaddr(EFL_NET_IP_ADDRESS_CLASS, a->ai_addr);
498 if (o) 512 if (!o) continue ;
499 { 513
500 if (!eina_array_push(r->results, o)) 514 eina_value_array_append(&r, o);
501 efl_unref(o); 515 efl_unref(o);
502 }
503 } 516 }
504 freeaddrinfo(result); 517 freeaddrinfo(result);
505 518
506 efl_promise_value_set(ctx->promise, r, _efl_net_ip_address_resolve_results_free); 519 if (!eina_value_pget(&r, &desc)) goto on_error;
520 if (!eina_value_struct_pset(&s, "results", &desc)) goto on_error;
521 eina_value_flush(&r);
522
523 eina_promise_resolve(ctx->promise, s);
524
525 eina_stringshare_replace(&ctx->request_address, NULL);
526 free(ctx);
527
528 return ;
529
530 on_error:
531 eina_promise_reject(ctx->promise, err);
532
533 eina_stringshare_replace(&ctx->request_address, NULL);
534 free(ctx);
507} 535}
508 536
509EOLIAN static Efl_Future * 537EOLIAN static Eina_Future *
510_efl_net_ip_address_resolve(Eo *cls EINA_UNUSED, void *pd EINA_UNUSED, const char *address, int family, int flags) 538_efl_net_ip_address_resolve(Eo *cls EINA_UNUSED, void *pd EINA_UNUSED, const char *address, int family, int flags)
511{ 539{
512 Efl_Net_Ip_Address_Resolve_Context *ctx; 540 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
538 ctx = calloc(1, sizeof(Efl_Net_Ip_Address_Resolve_Context)); 566 ctx = calloc(1, sizeof(Efl_Net_Ip_Address_Resolve_Context));
539 EINA_SAFETY_ON_NULL_GOTO(ctx, error_ctx); 567 EINA_SAFETY_ON_NULL_GOTO(ctx, error_ctx);
540 568
541 ctx->result = calloc(1, sizeof(Efl_Net_Ip_Address_Resolve_Results)); 569 ctx->request_address = eina_stringshare_add(address);
542 EINA_SAFETY_ON_NULL_GOTO(ctx->result, error_result); 570 EINA_SAFETY_ON_NULL_GOTO(ctx->request_address, error_result_address);
543
544 ctx->result->request_address = eina_stringshare_add(address);
545 EINA_SAFETY_ON_NULL_GOTO(ctx->result->request_address, error_result_address);
546 571
547 ctx->thread = efl_net_ip_resolve_async_new(host, port, &hints, _efl_net_ip_address_resolve_done, ctx); 572 ctx->thread = efl_net_ip_resolve_async_new(host, port, &hints, _efl_net_ip_address_resolve_done, ctx);
548 EINA_SAFETY_ON_NULL_GOTO(ctx->thread, error_thread); 573 EINA_SAFETY_ON_NULL_GOTO(ctx->thread, error_thread);
549 574
550 ctx->promise = efl_add(EFL_PROMISE_CLASS, efl_main_loop_get(), 575 ctx->promise = eina_promise_new(efl_loop_future_scheduler_get(efl_main_loop_get()), _efl_net_ip_address_resolve_del, ctx);
551 efl_event_callback_add(efl_added, EFL_EVENT_DEL, _efl_net_ip_address_resolve_del, ctx));
552 EINA_SAFETY_ON_NULL_GOTO(ctx->promise, error_promise); 576 EINA_SAFETY_ON_NULL_GOTO(ctx->promise, error_promise);
553 577
554 free(str); 578 free(str);
555 return efl_promise_future_get(ctx->promise); 579 return eina_future_new(ctx->promise);
556 580
557 error_promise: 581 error_promise:
558 ecore_thread_cancel(ctx->thread); 582 ecore_thread_cancel(ctx->thread);
559 error_thread: 583 error_thread:
560 eina_stringshare_del(ctx->result->request_address); 584 eina_stringshare_del(ctx->request_address);
561 error_result_address: 585 error_result_address:
562 free(ctx->result);
563 error_result:
564 free(ctx); 586 free(ctx);
565 error_ctx: 587 error_ctx:
566 free(str); 588 free(str);
diff --git a/src/lib/ecore_con/efl_net_ip_address.eo b/src/lib/ecore_con/efl_net_ip_address.eo
index e715a0c7bb..dfb99538b1 100644
--- a/src/lib/ecore_con/efl_net_ip_address.eo
+++ b/src/lib/ecore_con/efl_net_ip_address.eo
@@ -112,7 +112,7 @@ class Efl.Net.Ip_Address (Efl.Object) {
112 family: int @optional; [[Preferred family. AF_UNSPEC or 0 for both, otherwise one of AF_INET or AF_INET6]] 112 family: int @optional; [[Preferred family. AF_UNSPEC or 0 for both, otherwise one of AF_INET or AF_INET6]]
113 flags: int @optional; [[Flags to use with getaddrinfo(). If 0, default flags are used (AI_V4MAPPED | AI_ADDRCONFIG, if these exist in your system).]] 113 flags: int @optional; [[Flags to use with getaddrinfo(). If 0, default flags are used (AI_V4MAPPED | AI_ADDRCONFIG, if these exist in your system).]]
114 } 114 }
115 return: future<const(Efl.Net.Ip_Address.Resolve_Results)>; [[The resolve results. It contains a list of Efl.Net.Ip_Address, they will be automatically deleted unless you keep a reference to it.]] 115 return: ptr(Eina.Future); [[The resolve results. It contains a list of Efl.Net.Ip_Address, they will be automatically deleted unless you keep a reference to it.]]
116 } 116 }
117 117
118 @property string { 118 @property string {