efl/src/lib/eldbus/eldbus_proxy.c

902 lines
28 KiB
C
Raw Normal View History

2013-03-15 01:32:20 -07:00
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "eldbus_private.h"
#include "eldbus_private_types.h"
/* TODO: mempool of Eldbus_Proxy, Eldbus_Proxy_Context_Event_Cb and
* Eldbus_Proxy_Context_Event
*/
typedef struct _Eldbus_Proxy_Context_Event_Cb
{
EINA_INLIST;
Eldbus_Proxy_Event_Cb cb;
const void *cb_data;
Eina_Bool deleted : 1;
} Eldbus_Proxy_Context_Event_Cb;
typedef struct _Eldbus_Proxy_Context_Event
{
Eina_Inlist *list;
int walking;
Eina_List *to_delete;
} Eldbus_Proxy_Context_Event;
struct _Eldbus_Proxy
{
EINA_MAGIC;
int refcount;
Eldbus_Object *obj;
const char *interface;
Eina_Inlist *pendings;
Eina_List *handlers;
Eina_Inlist *cbs_free;
Eina_Inlist *data;
Eldbus_Proxy_Context_Event event_handlers[ELDBUS_PROXY_EVENT_LAST];
Eina_Hash *props;
Eldbus_Signal_Handler *properties_changed;
Eina_Bool monitor_enabled:1;
};
#define ELDBUS_PROXY_CHECK(proxy) \
do \
{ \
EINA_SAFETY_ON_NULL_RETURN(proxy); \
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
{ \
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
return; \
} \
EINA_SAFETY_ON_TRUE_RETURN(proxy->refcount <= 0); \
} \
while (0)
#define ELDBUS_PROXY_CHECK_RETVAL(proxy, retval) \
do \
{ \
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, retval); \
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
{ \
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
return retval; \
} \
EINA_SAFETY_ON_TRUE_RETURN_VAL(proxy->refcount <= 0, retval); \
} \
while (0)
#define ELDBUS_PROXY_CHECK_GOTO(proxy, label) \
do \
{ \
EINA_SAFETY_ON_NULL_GOTO(proxy, label); \
if (!EINA_MAGIC_CHECK(proxy, ELDBUS_PROXY_MAGIC)) \
{ \
EINA_MAGIC_FAIL(proxy, ELDBUS_PROXY_MAGIC); \
goto label; \
} \
EINA_SAFETY_ON_TRUE_GOTO(proxy->refcount <= 0, label); \
} \
while (0)
Eina_Bool
eldbus_proxy_init(void)
{
return EINA_TRUE;
}
void
eldbus_proxy_shutdown(void)
{
}
static void _eldbus_proxy_event_callback_call(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, const void *event_info);
static void _eldbus_proxy_context_event_cb_del(Eldbus_Proxy_Context_Event *ce, Eldbus_Proxy_Context_Event_Cb *ctx);
static void _on_signal_handler_free(void *data, const void *dead_pointer);
static void
_eldbus_proxy_call_del(Eldbus_Proxy *proxy)
{
Eldbus_Proxy_Context_Event *ce;
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_DEL, NULL);
/* clear all del callbacks so we don't call them twice at
* _eldbus_proxy_clear()
*/
ce = proxy->event_handlers + ELDBUS_PROXY_EVENT_DEL;
while (ce->list)
{
Eldbus_Proxy_Context_Event_Cb *ctx;
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
Eldbus_Proxy_Context_Event_Cb);
_eldbus_proxy_context_event_cb_del(ce, ctx);
}
}
static void
_eldbus_proxy_clear(Eldbus_Proxy *proxy)
{
Eldbus_Signal_Handler *h;
Eldbus_Pending *p;
Eina_List *iter, *iter_next;
Eina_Inlist *in_l;
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
proxy, proxy->refcount, proxy->interface, proxy->obj);
proxy->refcount = 1;
eldbus_object_proxy_del(proxy->obj, proxy, proxy->interface);
_eldbus_proxy_call_del(proxy);
EINA_LIST_FOREACH_SAFE(proxy->handlers, iter, iter_next, h)
{
DBG("proxy=%p delete owned signal handler %p %s",
proxy, h, eldbus_signal_handler_match_get(h));
eldbus_signal_handler_del(h);
}
EINA_INLIST_FOREACH_SAFE(proxy->pendings, in_l, p)
{
DBG("proxy=%p delete owned pending call=%p dest=%s path=%s %s.%s()",
proxy, p,
eldbus_pending_destination_get(p),
eldbus_pending_path_get(p),
eldbus_pending_interface_get(p),
eldbus_pending_method_get(p));
eldbus_pending_cancel(p);
}
eldbus_cbs_free_dispatch(&(proxy->cbs_free), proxy);
if (proxy->props)
{
eina_hash_free(proxy->props);
proxy->props = NULL;
}
proxy->refcount = 0;
}
static void
_eldbus_proxy_free(Eldbus_Proxy *proxy)
{
unsigned int i;
Eldbus_Signal_Handler *h;
DBG("freeing proxy=%p", proxy);
EINA_LIST_FREE(proxy->handlers, h)
{
if (h->dangling)
eldbus_signal_handler_free_cb_del(h, _on_signal_handler_free, proxy);
else
ERR("proxy=%p alive handler=%p %s", proxy, h,
eldbus_signal_handler_match_get(h));
}
if (proxy->pendings)
CRI("Proxy %p released with live pending calls!", proxy);
for (i = 0; i < ELDBUS_PROXY_EVENT_LAST; i++)
{
Eldbus_Proxy_Context_Event *ce = proxy->event_handlers + i;
while (ce->list)
{
Eldbus_Proxy_Context_Event_Cb *ctx;
ctx = EINA_INLIST_CONTAINER_GET(ce->list,
Eldbus_Proxy_Context_Event_Cb);
_eldbus_proxy_context_event_cb_del(ce, ctx);
}
eina_list_free(ce->to_delete);
}
eina_stringshare_del(proxy->interface);
EINA_MAGIC_SET(proxy, EINA_MAGIC_NONE);
free(proxy);
}
static void
_on_object_free(void *data, const void *dead_pointer EINA_UNUSED)
{
Eldbus_Proxy *proxy = data;
ELDBUS_PROXY_CHECK(proxy);
DBG("proxy=%p, refcount=%d, interface=%s, obj=%p",
proxy, proxy->refcount, proxy->interface, proxy->obj);
eldbus_data_del_all(&(proxy->data));
_eldbus_proxy_clear(proxy);
_eldbus_proxy_free(proxy);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Proxy *
eldbus_proxy_get(Eldbus_Object *obj, const char *interface)
{
Eldbus_Proxy *proxy;
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(interface, NULL);
proxy = eldbus_object_proxy_get(obj, interface);
if (proxy)
return eldbus_proxy_ref(proxy);
proxy = calloc(1, sizeof(Eldbus_Proxy));
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy, NULL);
proxy->refcount = 1;
proxy->obj = obj;
proxy->interface = eina_stringshare_add(interface);
EINA_MAGIC_SET(proxy, ELDBUS_PROXY_MAGIC);
if (!eldbus_object_proxy_add(obj, proxy))
goto cleanup;
eldbus_object_free_cb_add(obj, _on_object_free, proxy);
return proxy;
cleanup:
eina_stringshare_del(proxy->interface);
free(proxy);
return NULL;
}
static void _on_signal_handler_free(void *data, const void *dead_pointer);
static void
_eldbus_proxy_unref(Eldbus_Proxy *proxy)
{
proxy->refcount--;
if (proxy->refcount > 0) return;
eldbus_object_free_cb_del(proxy->obj, _on_object_free, proxy);
eldbus_data_del_all(&(proxy->data));
_eldbus_proxy_clear(proxy);
_eldbus_proxy_free(proxy);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Proxy *
eldbus_proxy_ref(Eldbus_Proxy *proxy)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
proxy, proxy->refcount, proxy->interface, proxy->obj);
proxy->refcount++;
return proxy;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_unref(Eldbus_Proxy *proxy)
{
ELDBUS_PROXY_CHECK(proxy);
DBG("proxy=%p, pre-refcount=%d, interface=%s, obj=%p",
proxy, proxy->refcount, proxy->interface, proxy->obj);
_eldbus_proxy_unref(proxy);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_free_cb_add(Eldbus_Proxy *proxy, Eldbus_Free_Cb cb, const void *data)
{
ELDBUS_PROXY_CHECK(proxy);
EINA_SAFETY_ON_NULL_RETURN(cb);
proxy->cbs_free = eldbus_cbs_free_add(proxy->cbs_free, cb, data);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_free_cb_del(Eldbus_Proxy *proxy, Eldbus_Free_Cb cb, const void *data)
{
ELDBUS_PROXY_CHECK(proxy);
EINA_SAFETY_ON_NULL_RETURN(cb);
proxy->cbs_free = eldbus_cbs_free_del(proxy->cbs_free, cb, data);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_data_set(Eldbus_Proxy *proxy, const char *key, const void *data)
{
ELDBUS_PROXY_CHECK(proxy);
EINA_SAFETY_ON_NULL_RETURN(key);
EINA_SAFETY_ON_NULL_RETURN(data);
eldbus_data_set(&(proxy->data), key, data);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void *
eldbus_proxy_data_get(const Eldbus_Proxy *proxy, const char *key)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
return eldbus_data_get(&(((Eldbus_Proxy *)proxy)->data), key);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void *
eldbus_proxy_data_del(Eldbus_Proxy *proxy, const char *key)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(key, NULL);
return eldbus_data_del(&(((Eldbus_Proxy *)proxy)->data), key);
}
static Eina_Value *
_iter_hash_value_set(Eina_Hash *props, const char *key, Eldbus_Message_Iter *var) EINA_ARG_NONNULL(1, 2, 3)
{
Eina_Value *st_value = _message_iter_struct_to_eina_value(var);
Eina_Value *value;
Eina_Value stack_value;
eina_value_struct_value_get(st_value, "arg0", &stack_value);
value = eina_hash_find(props, key);
if (!value)
{
value = eina_value_new(eina_value_type_get(&stack_value));
eina_hash_add(props, key, value);
}
eina_value_flush(value);
eina_value_copy(&stack_value, value);
eina_value_flush(&stack_value);
eina_value_free(st_value);
return value;
}
static void
_property_changed_iter(void *data, const void *key, Eldbus_Message_Iter *var)
{
Eldbus_Proxy *proxy = data;
const char *skey = key;
Eina_Value *value = _iter_hash_value_set(proxy->props, skey, var);
Eldbus_Proxy_Event_Property_Changed event = {.name = skey,
.value = value,
.proxy = proxy};
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
&event);
}
static void
_properties_changed(void *data, const Eldbus_Message *msg)
{
Eldbus_Proxy *proxy = data;
Eldbus_Message_Iter *array, *invalidate;
const char *iface;
const char *invalidate_prop;
if (!eldbus_message_arguments_get(msg, "sa{sv}as", &iface, &array, &invalidate))
{
ERR("Error getting data from properties changed signal.");
return;
}
if (proxy->props)
eldbus_message_iter_dict_iterate(array, "sv", _property_changed_iter,
proxy);
while (eldbus_message_iter_get_and_next(invalidate, 's', &invalidate_prop))
{
Eldbus_Proxy_Event_Property_Removed event;
event.interface = proxy->interface;
event.name = invalidate_prop;
event.proxy = proxy;
if (proxy->props)
eina_hash_del(proxy->props, event.name, NULL);
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_REMOVED,
&event);
}
}
static void
_props_cache_free(void *data)
{
Eina_Value *value = data;
eina_value_free(value);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_event_callback_add(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, Eldbus_Proxy_Event_Cb cb, const void *cb_data)
{
Eldbus_Proxy_Context_Event *ce;
Eldbus_Proxy_Context_Event_Cb *ctx;
ELDBUS_PROXY_CHECK(proxy);
EINA_SAFETY_ON_NULL_RETURN(cb);
EINA_SAFETY_ON_TRUE_RETURN(type >= ELDBUS_PROXY_EVENT_LAST);
ce = proxy->event_handlers + type;
ctx = calloc(1, sizeof(Eldbus_Proxy_Context_Event_Cb));
EINA_SAFETY_ON_NULL_RETURN(ctx);
ctx->cb = cb;
ctx->cb_data = cb_data;
ce->list = eina_inlist_append(ce->list, EINA_INLIST_GET(ctx));
if (type == ELDBUS_PROXY_EVENT_PROPERTY_CHANGED)
{
if (proxy->properties_changed) return;
if (!proxy->props)
proxy->props = eina_hash_string_superfast_new(_props_cache_free);
proxy->properties_changed =
eldbus_proxy_properties_changed_callback_add(proxy,
_properties_changed,
proxy);
}
else if (type == ELDBUS_PROXY_EVENT_PROPERTY_REMOVED)
{
if (proxy->properties_changed) return;
proxy->properties_changed =
eldbus_proxy_properties_changed_callback_add(proxy,
_properties_changed,
proxy);
}
}
static void
_eldbus_proxy_context_event_cb_del(Eldbus_Proxy_Context_Event *ce, Eldbus_Proxy_Context_Event_Cb *ctx)
{
ce->list = eina_inlist_remove(ce->list, EINA_INLIST_GET(ctx));
free(ctx);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API void
eldbus_proxy_event_callback_del(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, Eldbus_Proxy_Event_Cb cb, const void *cb_data)
{
Eldbus_Proxy_Context_Event *ce;
Eldbus_Proxy_Context_Event_Cb *iter, *found = NULL;
ELDBUS_PROXY_CHECK(proxy);
EINA_SAFETY_ON_NULL_RETURN(cb);
EINA_SAFETY_ON_TRUE_RETURN(type >= ELDBUS_PROXY_EVENT_LAST);
ce = proxy->event_handlers + type;
EINA_INLIST_FOREACH(ce->list, iter)
{
if (cb != iter->cb) continue;
if ((cb_data) && (cb_data != iter->cb_data)) continue;
found = iter;
break;
}
EINA_SAFETY_ON_NULL_RETURN(found);
EINA_SAFETY_ON_TRUE_RETURN(found->deleted);
if (ce->walking)
{
found->deleted = EINA_TRUE;
ce->to_delete = eina_list_append(ce->to_delete, found);
return;
}
_eldbus_proxy_context_event_cb_del(ce, found);
if (type == ELDBUS_PROXY_EVENT_PROPERTY_CHANGED)
{
Eldbus_Proxy_Context_Event *ce_prop_remove;
ce_prop_remove = proxy->event_handlers +
ELDBUS_PROXY_EVENT_PROPERTY_REMOVED;
if (!ce->list && !proxy->monitor_enabled)
{
eina_hash_free(proxy->props);
proxy->props = NULL;
}
if (!ce_prop_remove->list && !ce->list && !proxy->monitor_enabled)
{
eldbus_signal_handler_unref(proxy->properties_changed);
proxy->properties_changed = NULL;
}
}
else if (type == ELDBUS_PROXY_EVENT_PROPERTY_REMOVED)
{
Eldbus_Proxy_Context_Event *ce_prop_changed;
ce_prop_changed = proxy->event_handlers +
ELDBUS_PROXY_EVENT_PROPERTY_CHANGED;
if (!ce_prop_changed->list && !ce->list && !proxy->monitor_enabled)
{
eldbus_signal_handler_unref(proxy->properties_changed);
proxy->properties_changed = NULL;
}
}
}
static void
_eldbus_proxy_event_callback_call(Eldbus_Proxy *proxy, Eldbus_Proxy_Event_Type type, const void *event_info)
{
Eldbus_Proxy_Context_Event *ce;
Eldbus_Proxy_Context_Event_Cb *iter;
ce = proxy->event_handlers + type;
ce->walking++;
EINA_INLIST_FOREACH(ce->list, iter)
{
if (iter->deleted) continue;
iter->cb((void *)iter->cb_data, proxy, (void *)event_info);
}
ce->walking--;
if (ce->walking > 0) return;
EINA_LIST_FREE(ce->to_delete, iter)
_eldbus_proxy_context_event_cb_del(ce, iter);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Object *
eldbus_proxy_object_get(const Eldbus_Proxy *proxy)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
return proxy->obj;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API const char *
eldbus_proxy_interface_get(const Eldbus_Proxy *proxy)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
return proxy->interface;
}
static void
eldbus: Fix crash when removing the last reference of the message container inside of the message callback If user try to remove the last reference of proxy, object, connection or eldbus(lib) inside of message callback it was causing the eldbus_pending_dispatch() being called 2 times, one because of the eldbus_cancel() that is triggered when the last reference of the message parent is removed and another after the return of the user callback. ==6545== Invalid read of size 8 ==6545== at 0x52F784E: eldbus_cbs_free_dispatch (eldbus_core.c:266) ==6545== by 0x53064AA: eldbus_pending_dispatch (eldbus_pending.c:227) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) ==6545== by 0x4E4B300: _ecore_call_task_cb (ecore_private.h:305) ==6545== by 0x4E4B78F: _ecore_idler_all_call (ecore_idler.c:143) ==6545== by 0x4E4EA73: _ecore_main_loop_spin_core (ecore_main.c:1768) ==6545== by 0x4E4EAF1: _ecore_main_loop_spin_timers (ecore_main.c:1802) ==6545== by 0x4E4ED01: _ecore_main_loop_iterate_internal (ecore_main.c:1925) ==6545== by 0x4E4D03B: ecore_main_loop_begin (ecore_main.c:983) ==6545== Address 0x701aa78 is 104 bytes inside a block of size 128 free'd ==6545== at 0x4C2B200: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==6545== by 0x530655B: eldbus_pending_dispatch (eldbus_pending.c:241) ==6545== by 0x5306763: eldbus_pending_cancel (eldbus_pending.c:259) ==6545== by 0x52F29DB: _eldbus_proxy_clear (eldbus_proxy.c:146) ==6545== by 0x52F3057: _eldbus_proxy_unref (eldbus_proxy.c:244) ==6545== by 0x52F3393: eldbus_proxy_unref (eldbus_proxy.c:264) ==6545== by 0x401039: on_get_playlists (banshee.c:53) ==6545== by 0x5306493: eldbus_pending_dispatch (eldbus_pending.c:225) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) Now we will remove the pending from parent pending list before call the user callback, this way only the pending messages will be canceled. Also we need increase the eldbus reference before call dbus_connection_dispatch() or user could remove the last reference of eldbus inside of a message callback when we still are holding one reference of the connection. @fix ref T1908
2014-12-17 10:57:03 -08:00
_on_proxy_message_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
{
eldbus: Fix crash when removing the last reference of the message container inside of the message callback If user try to remove the last reference of proxy, object, connection or eldbus(lib) inside of message callback it was causing the eldbus_pending_dispatch() being called 2 times, one because of the eldbus_cancel() that is triggered when the last reference of the message parent is removed and another after the return of the user callback. ==6545== Invalid read of size 8 ==6545== at 0x52F784E: eldbus_cbs_free_dispatch (eldbus_core.c:266) ==6545== by 0x53064AA: eldbus_pending_dispatch (eldbus_pending.c:227) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) ==6545== by 0x4E4B300: _ecore_call_task_cb (ecore_private.h:305) ==6545== by 0x4E4B78F: _ecore_idler_all_call (ecore_idler.c:143) ==6545== by 0x4E4EA73: _ecore_main_loop_spin_core (ecore_main.c:1768) ==6545== by 0x4E4EAF1: _ecore_main_loop_spin_timers (ecore_main.c:1802) ==6545== by 0x4E4ED01: _ecore_main_loop_iterate_internal (ecore_main.c:1925) ==6545== by 0x4E4D03B: ecore_main_loop_begin (ecore_main.c:983) ==6545== Address 0x701aa78 is 104 bytes inside a block of size 128 free'd ==6545== at 0x4C2B200: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==6545== by 0x530655B: eldbus_pending_dispatch (eldbus_pending.c:241) ==6545== by 0x5306763: eldbus_pending_cancel (eldbus_pending.c:259) ==6545== by 0x52F29DB: _eldbus_proxy_clear (eldbus_proxy.c:146) ==6545== by 0x52F3057: _eldbus_proxy_unref (eldbus_proxy.c:244) ==6545== by 0x52F3393: eldbus_proxy_unref (eldbus_proxy.c:264) ==6545== by 0x401039: on_get_playlists (banshee.c:53) ==6545== by 0x5306493: eldbus_pending_dispatch (eldbus_pending.c:225) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) Now we will remove the pending from parent pending list before call the user callback, this way only the pending messages will be canceled. Also we need increase the eldbus reference before call dbus_connection_dispatch() or user could remove the last reference of eldbus inside of a message callback when we still are holding one reference of the connection. @fix ref T1908
2014-12-17 10:57:03 -08:00
Eldbus_Message_Cb cb = eldbus_pending_data_del(pending, "__user_cb");
Eldbus_Proxy *proxy = eldbus_pending_data_del(pending, "__proxy");
ELDBUS_PROXY_CHECK(proxy);
proxy->pendings = eina_inlist_remove(proxy->pendings,
EINA_INLIST_GET(pending));
eldbus: Fix crash when removing the last reference of the message container inside of the message callback If user try to remove the last reference of proxy, object, connection or eldbus(lib) inside of message callback it was causing the eldbus_pending_dispatch() being called 2 times, one because of the eldbus_cancel() that is triggered when the last reference of the message parent is removed and another after the return of the user callback. ==6545== Invalid read of size 8 ==6545== at 0x52F784E: eldbus_cbs_free_dispatch (eldbus_core.c:266) ==6545== by 0x53064AA: eldbus_pending_dispatch (eldbus_pending.c:227) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) ==6545== by 0x4E4B300: _ecore_call_task_cb (ecore_private.h:305) ==6545== by 0x4E4B78F: _ecore_idler_all_call (ecore_idler.c:143) ==6545== by 0x4E4EA73: _ecore_main_loop_spin_core (ecore_main.c:1768) ==6545== by 0x4E4EAF1: _ecore_main_loop_spin_timers (ecore_main.c:1802) ==6545== by 0x4E4ED01: _ecore_main_loop_iterate_internal (ecore_main.c:1925) ==6545== by 0x4E4D03B: ecore_main_loop_begin (ecore_main.c:983) ==6545== Address 0x701aa78 is 104 bytes inside a block of size 128 free'd ==6545== at 0x4C2B200: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==6545== by 0x530655B: eldbus_pending_dispatch (eldbus_pending.c:241) ==6545== by 0x5306763: eldbus_pending_cancel (eldbus_pending.c:259) ==6545== by 0x52F29DB: _eldbus_proxy_clear (eldbus_proxy.c:146) ==6545== by 0x52F3057: _eldbus_proxy_unref (eldbus_proxy.c:244) ==6545== by 0x52F3393: eldbus_proxy_unref (eldbus_proxy.c:264) ==6545== by 0x401039: on_get_playlists (banshee.c:53) ==6545== by 0x5306493: eldbus_pending_dispatch (eldbus_pending.c:225) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) Now we will remove the pending from parent pending list before call the user callback, this way only the pending messages will be canceled. Also we need increase the eldbus reference before call dbus_connection_dispatch() or user could remove the last reference of eldbus inside of a message callback when we still are holding one reference of the connection. @fix ref T1908
2014-12-17 10:57:03 -08:00
cb(data, msg, pending);
}
static Eldbus_Pending *
_eldbus_proxy_send(Eldbus_Proxy *proxy, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
{
Eldbus_Pending *pending;
eldbus: Fix crash when removing the last reference of the message container inside of the message callback If user try to remove the last reference of proxy, object, connection or eldbus(lib) inside of message callback it was causing the eldbus_pending_dispatch() being called 2 times, one because of the eldbus_cancel() that is triggered when the last reference of the message parent is removed and another after the return of the user callback. ==6545== Invalid read of size 8 ==6545== at 0x52F784E: eldbus_cbs_free_dispatch (eldbus_core.c:266) ==6545== by 0x53064AA: eldbus_pending_dispatch (eldbus_pending.c:227) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) ==6545== by 0x4E4B300: _ecore_call_task_cb (ecore_private.h:305) ==6545== by 0x4E4B78F: _ecore_idler_all_call (ecore_idler.c:143) ==6545== by 0x4E4EA73: _ecore_main_loop_spin_core (ecore_main.c:1768) ==6545== by 0x4E4EAF1: _ecore_main_loop_spin_timers (ecore_main.c:1802) ==6545== by 0x4E4ED01: _ecore_main_loop_iterate_internal (ecore_main.c:1925) ==6545== by 0x4E4D03B: ecore_main_loop_begin (ecore_main.c:983) ==6545== Address 0x701aa78 is 104 bytes inside a block of size 128 free'd ==6545== at 0x4C2B200: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==6545== by 0x530655B: eldbus_pending_dispatch (eldbus_pending.c:241) ==6545== by 0x5306763: eldbus_pending_cancel (eldbus_pending.c:259) ==6545== by 0x52F29DB: _eldbus_proxy_clear (eldbus_proxy.c:146) ==6545== by 0x52F3057: _eldbus_proxy_unref (eldbus_proxy.c:244) ==6545== by 0x52F3393: eldbus_proxy_unref (eldbus_proxy.c:264) ==6545== by 0x401039: on_get_playlists (banshee.c:53) ==6545== by 0x5306493: eldbus_pending_dispatch (eldbus_pending.c:225) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) Now we will remove the pending from parent pending list before call the user callback, this way only the pending messages will be canceled. Also we need increase the eldbus reference before call dbus_connection_dispatch() or user could remove the last reference of eldbus inside of a message callback when we still are holding one reference of the connection. @fix ref T1908
2014-12-17 10:57:03 -08:00
if (!cb)
{
_eldbus_connection_send(proxy->obj->conn, msg, NULL, NULL, timeout);
return NULL;
}
pending = _eldbus_connection_send(proxy->obj->conn, msg,
_on_proxy_message_cb, cb_data, timeout);
EINA_SAFETY_ON_NULL_RETURN_VAL(pending, NULL);
eldbus: Fix crash when removing the last reference of the message container inside of the message callback If user try to remove the last reference of proxy, object, connection or eldbus(lib) inside of message callback it was causing the eldbus_pending_dispatch() being called 2 times, one because of the eldbus_cancel() that is triggered when the last reference of the message parent is removed and another after the return of the user callback. ==6545== Invalid read of size 8 ==6545== at 0x52F784E: eldbus_cbs_free_dispatch (eldbus_core.c:266) ==6545== by 0x53064AA: eldbus_pending_dispatch (eldbus_pending.c:227) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) ==6545== by 0x4E4B300: _ecore_call_task_cb (ecore_private.h:305) ==6545== by 0x4E4B78F: _ecore_idler_all_call (ecore_idler.c:143) ==6545== by 0x4E4EA73: _ecore_main_loop_spin_core (ecore_main.c:1768) ==6545== by 0x4E4EAF1: _ecore_main_loop_spin_timers (ecore_main.c:1802) ==6545== by 0x4E4ED01: _ecore_main_loop_iterate_internal (ecore_main.c:1925) ==6545== by 0x4E4D03B: ecore_main_loop_begin (ecore_main.c:983) ==6545== Address 0x701aa78 is 104 bytes inside a block of size 128 free'd ==6545== at 0x4C2B200: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==6545== by 0x530655B: eldbus_pending_dispatch (eldbus_pending.c:241) ==6545== by 0x5306763: eldbus_pending_cancel (eldbus_pending.c:259) ==6545== by 0x52F29DB: _eldbus_proxy_clear (eldbus_proxy.c:146) ==6545== by 0x52F3057: _eldbus_proxy_unref (eldbus_proxy.c:244) ==6545== by 0x52F3393: eldbus_proxy_unref (eldbus_proxy.c:264) ==6545== by 0x401039: on_get_playlists (banshee.c:53) ==6545== by 0x5306493: eldbus_pending_dispatch (eldbus_pending.c:225) ==6545== by 0x5305961: cb_pending (eldbus_pending.c:74) ==6545== by 0x6B29DB1: ??? (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x6B2D280: dbus_connection_dispatch (in /usr/lib/libdbus-1.so.3.8.9) ==6545== by 0x52F93B4: eldbus_idler (eldbus_core.c:773) Now we will remove the pending from parent pending list before call the user callback, this way only the pending messages will be canceled. Also we need increase the eldbus reference before call dbus_connection_dispatch() or user could remove the last reference of eldbus inside of a message callback when we still are holding one reference of the connection. @fix ref T1908
2014-12-17 10:57:03 -08:00
eldbus_pending_data_set(pending, "__user_cb", cb);
eldbus_pending_data_set(pending, "__proxy", proxy);
proxy->pendings = eina_inlist_append(proxy->pendings,
EINA_INLIST_GET(pending));
return pending;
}
static Eldbus_Message *
_eldbus_proxy_send_and_block(Eldbus_Proxy *proxy, Eldbus_Message *msg, double timeout)
{
return _eldbus_connection_send_and_block(proxy->obj->conn, msg, timeout);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_send(Eldbus_Proxy *proxy, Eldbus_Message *msg, Eldbus_Message_Cb cb, const void *cb_data, double timeout)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
return _eldbus_proxy_send(proxy, msg, cb, cb_data, timeout);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Message *
eldbus_proxy_send_and_block(Eldbus_Proxy *proxy, Eldbus_Message *msg, double timeout)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
return _eldbus_proxy_send_and_block(proxy, msg, timeout);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Message *
eldbus_proxy_method_call_new(Eldbus_Proxy *proxy, const char *member)
{
Eldbus_Message *msg;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
msg = eldbus_message_method_call_new(
eldbus_object_bus_name_get(proxy->obj),
eldbus_object_path_get(proxy->obj),
proxy->interface, member);
return msg;
}
static Eldbus_Pending *
_eldbus_proxy_vcall(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
{
Eldbus_Message *msg = eldbus_proxy_method_call_new(proxy, member);
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, NULL);
if (!eldbus_message_arguments_vappend(msg, signature, ap))
{
eldbus_message_unref(msg);
ERR("Error setting arguments");
return NULL;
}
return _eldbus_proxy_send(proxy, msg, cb, cb_data, timeout);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_call(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, ...)
{
Eldbus_Pending *pending;
va_list ap;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
va_start(ap, signature);
pending = _eldbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
signature, ap);
va_end(ap);
return pending;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_vcall(Eldbus_Proxy *proxy, const char *member, Eldbus_Message_Cb cb, const void *cb_data, double timeout, const char *signature, va_list ap)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(member, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(signature, NULL);
return _eldbus_proxy_vcall(proxy, member, cb, cb_data, timeout,
signature, ap);
}
static void
_on_signal_handler_free(void *data, const void *dead_pointer)
{
Eldbus_Proxy *proxy = data;
ELDBUS_PROXY_CHECK(proxy);
proxy->handlers = eina_list_remove(proxy->handlers, dead_pointer);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Signal_Handler *
eldbus_proxy_signal_handler_add(Eldbus_Proxy *proxy, const char *member, Eldbus_Signal_Cb cb, const void *cb_data)
{
Eldbus_Signal_Handler *handler;
const char *name, *path;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
name = eldbus_object_bus_name_get(proxy->obj);
path = eldbus_object_path_get(proxy->obj);
handler = _eldbus_signal_handler_add(proxy->obj->conn, name, path,
edbus: Fix bug found in refactored banshee example Refactor edbus_signal_handler_add() so internal signal handlers don't set the connection free callback. This fixes the bug in which EDBus_Connection was freeing the signal handler of EDBus_Conenction_Name ==22814== Invalid read of size 4 ==22814== at 0x40564B0: edbus_signal_handler_del (edbus_signal_handler.c:278) ==22814== by 0x4040E65: _edbus_connection_name_unref (edbus_core.c:507) ==22814== by 0x404106B: edbus_connection_name_owner_monitor (edbus_core.c:520) ==22814== by 0x4055F63: _edbus_signal_handler_clean (edbus_signal_handler.c:217) ==22814== by 0x40564F8: edbus_signal_handler_del (edbus_signal_handler.c:279) ==22814== by 0x4043088: _edbus_connection_unref (edbus_core.c:1045) ==22814== by 0x404352F: edbus_connection_unref (edbus_core.c:1105) ==22814== by 0x80498AA: main (banshee.c:233) ==22814== Address 0x44bea48 is 0 bytes inside a block of size 72 free'd ==22814== at 0x402C06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==22814== by 0x4056118: _edbus_signal_handler_del (edbus_signal_handler.c:249) ==22814== by 0x4056401: edbus_signal_handler_unref (edbus_signal_handler.c:272) ==22814== by 0x4056503: edbus_signal_handler_del (edbus_signal_handler.c:280) ==22814== by 0x4043088: _edbus_connection_unref (edbus_core.c:1045) ==22814== by 0x404352F: edbus_connection_unref (edbus_core.c:1105) ==22814== by 0x80498AA: main (banshee.c:233) ==22814== CRI<22814>: src/lib/edbus_signal_handler.c:278 edbus_signal_handler_del() *** Eina Magic Check Failed !!! Input handle has already been freed! *** NAUGHTY PROGRAMMER!!! *** SPANK SPANK SPANK!!! *** Now go fix your code. Tut tut tut! Patch by: José Roberto de Souza <zehortigoza@profusion.mobi> SVN revision: 80686
2012-12-11 11:50:01 -08:00
proxy->interface, member, cb, cb_data);
EINA_SAFETY_ON_NULL_RETURN_VAL(handler, NULL);
DBG("signal handler added: proxy=%p handler=%p cb=%p", proxy, handler, cb);
eldbus_signal_handler_free_cb_add(handler, _on_signal_handler_free, proxy);
proxy->handlers = eina_list_append(proxy->handlers, handler);
return handler;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_property_get(Eldbus_Proxy *proxy, const char *name, Eldbus_Message_Cb cb, const void *data)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
return eldbus_proxy_call(proxy->obj->properties, "Get", cb, data, -1,
"ss", proxy->interface, name);
}
static inline Eina_Bool
_type_is_number(char sig)
{
switch (sig)
{
case 'y': case 'b': case 'n': case 'q': case 'i':
case 'u': case 'x': case 't': case 'd': case 'h':
return EINA_TRUE;
default:
break;
}
return EINA_FALSE;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_property_set(Eldbus_Proxy *proxy, const char *name, const char *sig, const void *value, Eldbus_Message_Cb cb, const void *data)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *variant;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(sig, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate_single(sig, NULL), NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL((_type_is_number(sig[0]) || value), NULL);
msg = eldbus_proxy_method_call_new(proxy->obj->properties, "Set");
iter = eldbus_message_iter_get(msg);
eldbus_message_iter_basic_append(iter, 's', proxy->interface);
eldbus_message_iter_basic_append(iter, 's', name);
variant = eldbus_message_iter_container_new(iter, 'v', sig);
if (dbus_type_is_basic(sig[0]))
dbus_message_iter_append_basic(&variant->dbus_iterator, sig[0], &value);
else
{
if (!_message_iter_from_eina_value_struct(sig, variant, value))
{
eldbus_message_unref(msg);
return NULL;
}
}
eldbus_message_iter_container_close(iter, variant);
return eldbus_proxy_send(proxy->obj->properties, msg, cb, data, -1);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_property_value_set(Eldbus_Proxy *proxy, const char *name, const char *sig, const Eina_Value *value, Eldbus_Message_Cb cb, const void *data)
{
Eldbus_Message *msg;
Eldbus_Message_Iter *iter, *variant;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(sig, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(dbus_signature_validate_single(sig, NULL), NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL((_type_is_number(sig[0]) || value), NULL);
msg = eldbus_proxy_method_call_new(proxy->obj->properties, "Set");
iter = eldbus_message_iter_get(msg);
eldbus_message_iter_basic_append(iter, 's', proxy->interface);
eldbus_message_iter_basic_append(iter, 's', name);
variant = eldbus_message_iter_container_new(iter, 'v', sig);
if (dbus_type_is_basic(sig[0]))
{
if (!_message_iter_from_eina_value(sig, variant, value))
goto error;
}
else
{
if (!_message_iter_from_eina_value_struct(sig, variant, value))
goto error;
}
eldbus_message_iter_container_close(iter, variant);
return eldbus_proxy_send(proxy->obj->properties, msg, cb, data, -1);
error:
eldbus_message_unref(msg);
return NULL;
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Pending *
eldbus_proxy_property_get_all(Eldbus_Proxy *proxy, Eldbus_Message_Cb cb, const void *data)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
return eldbus_proxy_call(proxy->obj->properties, "GetAll", cb, data, -1,
"s", proxy->interface);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eldbus_Signal_Handler *
eldbus_proxy_properties_changed_callback_add(Eldbus_Proxy *proxy, Eldbus_Signal_Cb cb, const void *data)
{
Eldbus_Signal_Handler *sh;
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
sh = eldbus_proxy_signal_handler_add(proxy->obj->properties,
"PropertiesChanged", cb, data);
EINA_SAFETY_ON_NULL_RETURN_VAL(sh, NULL);
eldbus_signal_handler_match_extra_set(sh, "arg0", proxy->interface, NULL);
return sh;
}
static void
_property_iter(void *data, const void *key, Eldbus_Message_Iter *var)
{
Eldbus_Proxy *proxy = data;
const char *skey = key;
_iter_hash_value_set(proxy->props, skey, var);
}
static void
_on_monitored_proxy_del(void *data, Eldbus_Proxy *proxy EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eldbus_Pending *pending = data;
eldbus_pending_cancel(pending);
}
static void
_props_get_all(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending)
{
Eldbus_Proxy *proxy = data;
Eldbus_Message_Iter *dict;
const char *name, *error_msg;
Eldbus_Proxy_Event_Property_Loaded event;
eldbus_proxy_event_callback_del(proxy, ELDBUS_PROXY_EVENT_DEL,
_on_monitored_proxy_del, pending);
if (eldbus_message_error_get(msg, &name, &error_msg))
{
/* don't print warnings for user-canceled calls */
if (!eina_streq(name, "org.enlightenment.DBus.Canceled"))
WRN("Error getting all properties of %s %s, error message: %s %s",
proxy->obj->name, proxy->obj->path, name, error_msg);
return;
}
if (!eldbus_message_arguments_get(msg, "a{sv}", &dict))
{
char *txt;
if (eldbus_message_arguments_get(msg, "s", &txt))
WRN("Error getting data from properties getAll: %s", txt);
return;
}
eldbus_message_iter_dict_iterate(dict, "sv", _property_iter, proxy);
event.proxy = proxy;
_eldbus_proxy_event_callback_call(proxy, ELDBUS_PROXY_EVENT_PROPERTY_LOADED,
&event);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eina_Bool
eldbus_proxy_properties_monitor(Eldbus_Proxy *proxy, Eina_Bool enable)
{
Eldbus_Pending *pending;
ELDBUS_PROXY_CHECK_RETVAL(proxy, EINA_FALSE);
if (proxy->monitor_enabled == enable)
return proxy->props ? !!eina_hash_population(proxy->props) : EINA_FALSE;
proxy->monitor_enabled = enable;
if (!enable)
{
Eldbus_Proxy_Context_Event *ce_prop_changed, *ce_prop_removed;
ce_prop_changed = proxy->event_handlers + ELDBUS_PROXY_EVENT_PROPERTY_CHANGED;
ce_prop_removed = proxy->event_handlers + ELDBUS_PROXY_EVENT_PROPERTY_REMOVED;
if (!ce_prop_changed->list)
{
eina_hash_free(proxy->props);
proxy->props = NULL;
}
if (!ce_prop_changed->list && !ce_prop_removed->list)
{
eldbus_signal_handler_unref(proxy->properties_changed);
proxy->properties_changed = NULL;
}
return EINA_TRUE;
}
if (!proxy->props)
proxy->props = eina_hash_string_superfast_new(_props_cache_free);
pending = eldbus_proxy_property_get_all(proxy, _props_get_all, proxy);
eldbus_proxy_event_callback_add(proxy, ELDBUS_PROXY_EVENT_DEL,
_on_monitored_proxy_del, pending);
if (proxy->properties_changed)
return !!eina_hash_population(proxy->props);
proxy->properties_changed =
eldbus_proxy_properties_changed_callback_add(proxy,
_properties_changed,
proxy);
return !!eina_hash_population(proxy->props);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API Eina_Value *
eldbus_proxy_property_local_get(Eldbus_Proxy *proxy, const char *name)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy->props, NULL);
return eina_hash_find(proxy->props, name);
}
eldbus: Rename EAPI macro to ELDBUS_API in Eldbus library Summary: = The Rationale = EAPI was designed to be able to pass `__attribute__ ((visibility ("default")))` for symbols with GCC, which would mean that even if -fvisibility=hidden was used when compiling the library, the needed symbols would get exported. MSVC __almost__ works like GCC (or mingw) in which you can declare everything as export and it will just work (slower, but it will work). But there's a caveat: global variables will not work the same way for MSVC, but works for mingw and GCC. For global variables (as opposed to functions), MSVC requires correct DSO visibility for MSVC: instead of declaring a symbol as export for everything, you need to declare it as import when importing from another DSO and export when defining it locally. With current EAPI definitions, we get the following example working in mingw and MSVC (observe it doesn't define any global variables as exported symbols). Example 1: dll1: ``` EAPI void foo(void); EAPI void bar() { foo(); } ``` dll2: ``` EAPI void foo() { printf ("foo\n"); } ``` This works fine with API defined as __declspec(dllexport) in both cases and for gcc defining as `__atttribute__((visibility("default")))`. However, the following: Example 2: dll1: ``` EAPI extern int foo; EAPI void foobar(void); EAPI void bar() { foo = 5; foobar(); } ``` dll2: ``` EAPI int foo = 0; EAPI void foobar() { printf ("foo %d\n", foo); } ``` This will work on mingw but will not work for MSVC. And that's why EAPI is the only solution that worked for MSVC. Co-authored-by: João Paulo Taylor Ienczak Zanette <jpaulotiz@gmail.com> Co-authored-by: Ricardo Campos <ricardo.campos@expertise.dev> Co-authored-by: Lucas Cavalcante de Sousa <lucks.sousa@gmail.com> Reviewers: vtorri, raster Subscribers: raster, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D12270
2021-05-23 12:07:51 -07:00
ELDBUS_API const Eina_Hash *
eldbus_proxy_property_local_get_all(Eldbus_Proxy *proxy)
{
ELDBUS_PROXY_CHECK_RETVAL(proxy, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(proxy->props, NULL);
return proxy->props;
}