Eo: add support for initialising eo after it has been shut down.
Until now it wasn't allowed/possible to init (eo_init) eo after it has
been shut down (eo_shutdown). This commit fixes that, so now that is
fully legal to have as many init/shutdown cycles as you want.
There was a previous workaround for this issue:
e47edc250d
.
This should allow more flexibility when using the EFL in loadable
modules and in various other scenarios.
The problem is that the class_get() functions cache the previously
created class for efficiency, but the class is freed if eo is shut down,
so the cached pointer is actually invalid.
The solution to the problem was to maintain a generation count
(incremented every time we shut down eo), and compare that to a locally
saved version in class_get(). If they don't match, recreate the class,
as it has already been freed.
@feature
This commit is contained in:
parent
43d05a334d
commit
668fd4a6e8
|
@ -53,7 +53,7 @@ static const char
|
|||
tmpl_eo_obj_header[] = "\
|
||||
#define @#CLASS_@#CLASSTYPE @#klasstype_get()\n\
|
||||
\n\
|
||||
EAPI const Eo_Class *@#klasstype_get(void) EINA_CONST;\n\
|
||||
EAPI const Eo_Class *@#klasstype_get(void);\n\
|
||||
\n\
|
||||
";
|
||||
|
||||
|
|
|
@ -123,6 +123,15 @@ typedef Eo Eo_Class;
|
|||
*/
|
||||
EAPI extern Eina_Spinlock _eo_class_creation_lock;
|
||||
|
||||
/**
|
||||
* @var _eo_init_generation
|
||||
* This variable stores the current eo init generation. That is, how many times
|
||||
* we have completed full init/shutdown cycles. Starts at 1 and incremeted on
|
||||
* every call to shutdown that actually shuts down eo.
|
||||
* @internal
|
||||
*/
|
||||
EAPI extern unsigned int _eo_init_generation;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* An enum representing the possible types of an Op.
|
||||
|
@ -292,6 +301,12 @@ class_get_func_name(void) \
|
|||
static volatile char lk_init = 0; \
|
||||
static Eina_Spinlock _my_lock; \
|
||||
static const Eo_Class * volatile _my_class = NULL; \
|
||||
static unsigned int _my_init_generation = 1; \
|
||||
if (EINA_UNLIKELY(_eo_init_generation != _my_init_generation)) \
|
||||
{ \
|
||||
_my_class = NULL; /* It's freed in eo_shutdown(). */ \
|
||||
lk_init = 0; \
|
||||
} \
|
||||
if (EINA_LIKELY(!!_my_class)) return _my_class; \
|
||||
\
|
||||
eina_spinlock_take(&_eo_class_creation_lock); \
|
||||
|
@ -309,6 +324,7 @@ class_get_func_name(void) \
|
|||
eina_spinlock_release(&_eo_class_creation_lock); \
|
||||
_tmp_parent_class = parent_class; \
|
||||
_my_class = eo_class_new(class_desc, _tmp_parent_class, __VA_ARGS__); \
|
||||
_my_init_generation = _eo_init_generation; \
|
||||
eina_spinlock_release(&_my_lock); \
|
||||
\
|
||||
eina_spinlock_take(&_eo_class_creation_lock); \
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
/* Used inside the class_get functions of classes, see #EO_DEFINE_CLASS */
|
||||
EAPI Eina_Spinlock _eo_class_creation_lock;
|
||||
EAPI unsigned int _eo_init_generation = 1;
|
||||
int _eo_log_dom = -1;
|
||||
|
||||
static _Eo_Class **_eo_classes;
|
||||
|
@ -1876,13 +1877,18 @@ eo_shutdown(void)
|
|||
eina_spinlock_free(&_eo_class_creation_lock);
|
||||
|
||||
if (_eo_call_stack_key != 0)
|
||||
eina_tls_free(_eo_call_stack_key);
|
||||
{
|
||||
eina_tls_free(_eo_call_stack_key);
|
||||
_eo_call_stack_key = 0;
|
||||
}
|
||||
|
||||
_eo_free_ids_tables();
|
||||
|
||||
eina_log_domain_unregister(_eo_log_dom);
|
||||
_eo_log_dom = -1;
|
||||
|
||||
++_eo_init_generation;
|
||||
|
||||
eina_shutdown();
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ typedef Eo Class_Simple;
|
|||
*/
|
||||
#define CLASS_SIMPLE_CLASS class_simple_class_get()
|
||||
|
||||
EAPI const Eo_Class *class_simple_class_get(void) EINA_CONST;
|
||||
EAPI const Eo_Class *class_simple_class_get(void);
|
||||
|
||||
#ifdef CLASS_SIMPLE_BETA
|
||||
/**
|
||||
|
|
|
@ -77,7 +77,7 @@ typedef struct _Opaque Opaque;
|
|||
*/
|
||||
#define DOCS_CLASS docs_class_get()
|
||||
|
||||
EAPI const Eo_Class *docs_class_get(void) EINA_CONST;
|
||||
EAPI const Eo_Class *docs_class_get(void);
|
||||
|
||||
/**
|
||||
* @brief Property common documentation.
|
||||
|
|
|
@ -28,7 +28,7 @@ typedef struct _Opaque Opaque;
|
|||
#endif
|
||||
#define STRUCT_CLASS struct_class_get()
|
||||
|
||||
EAPI const Eo_Class *struct_class_get(void) EINA_CONST;
|
||||
EAPI const Eo_Class *struct_class_get(void);
|
||||
|
||||
/**
|
||||
* @brief Foo docs. This is @c monospace. This is alone-standing $.
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef enum
|
|||
#endif
|
||||
#define TYPEDEF_CLASS typedef_class_get()
|
||||
|
||||
EAPI const Eo_Class *typedef_class_get(void) EINA_CONST;
|
||||
EAPI const Eo_Class *typedef_class_get(void);
|
||||
|
||||
EOAPI char *typedef_foo(int idx);
|
||||
|
||||
|
|
Loading…
Reference in New Issue