forked from enlightenment/efl
parent
ccf4af02aa
commit
54a2db0044
|
@ -360,3 +360,7 @@
|
|||
2011-11-29 Mike McCormack
|
||||
|
||||
* Allow quitting before entering the glib version of the main loop
|
||||
|
||||
2011-12-02 Mike Blumenkrantz
|
||||
|
||||
* Use mempools for allocations
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
Ecore 1.2.0
|
||||
|
||||
Changes since Ecore 1.1.0:
|
||||
--------------------------
|
||||
|
||||
Improvements:
|
||||
* ecore:
|
||||
- most allocations moved to mempools
|
||||
|
||||
|
||||
Ecore 1.1.0
|
||||
|
||||
Changes since Ecore 1.0.0:
|
||||
|
|
|
@ -11,6 +11,7 @@ includesdir = $(includedir)/ecore-@VMAJ@
|
|||
|
||||
libecore_la_SOURCES = \
|
||||
ecore.c \
|
||||
ecore_alloc.c \
|
||||
ecore_anim.c \
|
||||
ecore_app.c \
|
||||
ecore_events.c \
|
||||
|
|
|
@ -159,6 +159,7 @@ ecore_init(void)
|
|||
}
|
||||
if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
|
||||
if (_ecore_fps_debug) _ecore_fps_debug_init();
|
||||
if (!ecore_mempool_init()) goto shutdown_mempool;
|
||||
_ecore_main_loop_init();
|
||||
_ecore_signal_init();
|
||||
_ecore_thread_init();
|
||||
|
@ -191,6 +192,8 @@ ecore_init(void)
|
|||
|
||||
return _ecore_init_count;
|
||||
|
||||
shutdown_mempool:
|
||||
ecore_mempool_shutdown();
|
||||
shutdown_log_dom:
|
||||
eina_shutdown();
|
||||
shutdown_evil:
|
||||
|
@ -255,7 +258,7 @@ ecore_shutdown(void)
|
|||
_ecore_memory_max_free);
|
||||
}
|
||||
#endif
|
||||
|
||||
ecore_mempool_shutdown();
|
||||
eina_log_domain_unregister(_ecore_log_dom);
|
||||
_ecore_log_dom = -1;
|
||||
eina_shutdown();
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
typedef struct _Ecore_Mempool Ecore_Mempool;
|
||||
struct _Ecore_Mempool
|
||||
{
|
||||
const char *name;
|
||||
Eina_Mempool *mp;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#define GENERIC_ALLOC_FREE(TYPE, Type) \
|
||||
Ecore_Mempool Type##_mp = { #TYPE, NULL, sizeof (TYPE) }; \
|
||||
TYPE * \
|
||||
Type##_calloc(unsigned int num) \
|
||||
{ \
|
||||
return eina_mempool_calloc(Type##_mp.mp, num * sizeof (TYPE)); \
|
||||
} \
|
||||
void \
|
||||
Type##_mp_free(TYPE *e) \
|
||||
{ \
|
||||
eina_mempool_free(Type##_mp.mp, e); \
|
||||
}
|
||||
|
||||
GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator);
|
||||
GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler);
|
||||
GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter);
|
||||
GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
|
||||
GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter);
|
||||
GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer);
|
||||
GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler);
|
||||
GENERIC_ALLOC_FREE(Ecore_Job, ecore_job);
|
||||
GENERIC_ALLOC_FREE(Ecore_Timer, ecore_timer);
|
||||
GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller);
|
||||
GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe);
|
||||
GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler);
|
||||
#ifdef _WIN32
|
||||
GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
|
||||
#endif
|
||||
|
||||
static Ecore_Mempool *mempool_array[] = {
|
||||
&ecore_animator_mp,
|
||||
&ecore_event_handler_mp,
|
||||
&ecore_event_filter_mp,
|
||||
&ecore_event_mp,
|
||||
&ecore_idle_exiter_mp,
|
||||
&ecore_idle_enterer_mp,
|
||||
&ecore_idler_mp,
|
||||
&ecore_job_mp,
|
||||
&ecore_timer_mp,
|
||||
&ecore_poller_mp,
|
||||
&ecore_pipe_mp,
|
||||
&ecore_fd_handler_mp,
|
||||
#ifdef _WIN32
|
||||
&ecore_win32_handler_mp
|
||||
#endif
|
||||
};
|
||||
|
||||
Eina_Bool
|
||||
ecore_mempool_init(void)
|
||||
{
|
||||
const char *choice;
|
||||
unsigned int i;
|
||||
|
||||
choice = getenv("EINA_MEMPOOL");
|
||||
if ((!choice) || (!choice[0]))
|
||||
choice = "chained_mempool";
|
||||
|
||||
for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
|
||||
{
|
||||
retry:
|
||||
mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 64);
|
||||
if (!mempool_array[i]->mp)
|
||||
{
|
||||
if (!strcmp(choice, "pass_through"))
|
||||
{
|
||||
ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice);
|
||||
choice = "pass_through";
|
||||
goto retry;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Impossible to allocate mempool '%s' !", choice);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_mempool_shutdown(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
|
||||
{
|
||||
eina_mempool_del(mempool_array[i]->mp);
|
||||
mempool_array[i]->mp = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,22 +8,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
struct _Ecore_Animator
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
|
||||
double start, run;
|
||||
Ecore_Timeline_Cb run_func;
|
||||
void *run_data;
|
||||
|
||||
Eina_Bool delete_me : 1;
|
||||
Eina_Bool suspended : 1;
|
||||
};
|
||||
|
||||
static Eina_Bool _ecore_animator_run(void *data);
|
||||
static Eina_Bool _ecore_animator(void *data);
|
||||
|
||||
|
@ -121,7 +105,7 @@ _do_tick(void)
|
|||
eina_inlist_remove(EINA_INLIST_GET(animators),
|
||||
EINA_INLIST_GET(animator));
|
||||
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
|
||||
free(animator);
|
||||
ecore_animator_mp_free(animator);
|
||||
animators_delete_me--;
|
||||
if (animators_delete_me == 0) break;
|
||||
}
|
||||
|
@ -142,7 +126,7 @@ _ecore_animator_add(Ecore_Task_Cb func,
|
|||
Ecore_Animator *animator = NULL;
|
||||
|
||||
if (!func) return animator;
|
||||
animator = calloc(1, sizeof(Ecore_Animator));
|
||||
animator = ecore_animator_calloc(1);
|
||||
if (!animator) return animator;
|
||||
ECORE_MAGIC_SET(animator, ECORE_MAGIC_ANIMATOR);
|
||||
animator->func = func;
|
||||
|
@ -443,7 +427,7 @@ _ecore_animator_shutdown(void)
|
|||
animator = animators;
|
||||
animators = (Ecore_Animator *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
|
||||
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
|
||||
free(animator);
|
||||
ecore_animator_mp_free(animator);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,42 +9,6 @@
|
|||
|
||||
static int inpurge = 0;
|
||||
|
||||
struct _Ecore_Event_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int type;
|
||||
Ecore_Event_Handler_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Event_Filter
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Data_Cb func_start;
|
||||
Ecore_Filter_Cb func_filter;
|
||||
Ecore_End_Cb func_end;
|
||||
void *loop_data;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Event
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int type;
|
||||
void *event;
|
||||
Ecore_End_Cb func_free;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
static int events_num = 0;
|
||||
static Ecore_Event *events = NULL;
|
||||
static Ecore_Event *event_current = NULL;
|
||||
|
@ -109,7 +73,7 @@ ecore_event_handler_add(int type,
|
|||
|
||||
if (!func) goto unlock;
|
||||
if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) goto unlock;
|
||||
eh = calloc(1, sizeof(Ecore_Event_Handler));
|
||||
eh = ecore_event_handler_calloc(1);
|
||||
if (!eh) goto unlock;
|
||||
ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
|
||||
eh->type = type;
|
||||
|
@ -130,7 +94,7 @@ ecore_event_handler_add(int type,
|
|||
new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
|
||||
if (!new_handlers)
|
||||
{
|
||||
free(eh);
|
||||
ecore_event_handler_mp_free(eh);
|
||||
goto unlock;
|
||||
}
|
||||
event_handlers = new_handlers;
|
||||
|
@ -234,7 +198,7 @@ unlock:
|
|||
static void
|
||||
_ecore_event_generic_free(void *data __UNUSED__,
|
||||
void *event)
|
||||
{
|
||||
{ /* DO NOT MEMPOOL FREE THIS */
|
||||
free (event);
|
||||
}
|
||||
|
||||
|
@ -358,7 +322,7 @@ ecore_event_filter_add(Ecore_Data_Cb func_start,
|
|||
|
||||
_ecore_lock();
|
||||
if (!func_filter) goto unlock;
|
||||
ef = calloc(1, sizeof(Ecore_Event_Filter));
|
||||
ef = ecore_event_filter_calloc(1);
|
||||
if (!ef) goto unlock;
|
||||
ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
|
||||
ef->func_start = func_start;
|
||||
|
@ -469,11 +433,11 @@ _ecore_event_shutdown(void)
|
|||
{
|
||||
event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
|
||||
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
|
||||
if (!eh->delete_me) free(eh);
|
||||
if (!eh->delete_me) ecore_event_handler_mp_free(eh);
|
||||
}
|
||||
}
|
||||
EINA_LIST_FREE(event_handlers_delete_list, eh)
|
||||
free(eh);
|
||||
ecore_event_handler_mp_free(eh);
|
||||
if (event_handlers) free(event_handlers);
|
||||
event_handlers = NULL;
|
||||
event_handlers_num = 0;
|
||||
|
@ -482,7 +446,7 @@ _ecore_event_shutdown(void)
|
|||
{
|
||||
event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
|
||||
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
|
||||
free(ef);
|
||||
ecore_event_filter_mp_free(ef);
|
||||
}
|
||||
event_filters_delete_me = 0;
|
||||
event_filter_current = NULL;
|
||||
|
@ -506,7 +470,7 @@ _ecore_event_add(int type,
|
|||
{
|
||||
Ecore_Event *e;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_Event));
|
||||
e = ecore_event_calloc(1);
|
||||
if (!e) return NULL;
|
||||
ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
|
||||
e->type = type;
|
||||
|
@ -535,7 +499,7 @@ _ecore_event_del(Ecore_Event *event)
|
|||
if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event);
|
||||
events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
|
||||
ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
|
||||
free(event);
|
||||
ecore_event_mp_free(event);
|
||||
events_num--;
|
||||
return data;
|
||||
}
|
||||
|
@ -638,7 +602,7 @@ _ecore_event_filters_apply()
|
|||
|
||||
event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
|
||||
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
|
||||
free(ef);
|
||||
ecore_event_filter_mp_free(ef);
|
||||
}
|
||||
}
|
||||
if (!deleted_in_use)
|
||||
|
@ -742,7 +706,7 @@ _ecore_event_call(void)
|
|||
|
||||
event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
|
||||
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
|
||||
free(eh);
|
||||
ecore_event_handler_mp_free(eh);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
struct _Ecore_Idle_Enterer
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
static Ecore_Idle_Enterer *idle_enterers = NULL;
|
||||
static Ecore_Idle_Enterer *idle_enterer_current = NULL;
|
||||
static int idle_enterers_delete_me = 0;
|
||||
|
@ -49,7 +39,7 @@ ecore_idle_enterer_add(Ecore_Task_Cb func,
|
|||
_ecore_lock();
|
||||
|
||||
if (!func) goto unlock;
|
||||
ie = calloc(1, sizeof(Ecore_Idle_Enterer));
|
||||
ie = ecore_idle_enterer_calloc(1);
|
||||
if (!ie) goto unlock;
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
|
||||
ie->func = func;
|
||||
|
@ -79,7 +69,7 @@ ecore_idle_enterer_before_add(Ecore_Task_Cb func,
|
|||
_ecore_lock();
|
||||
|
||||
if (!func) goto unlock;
|
||||
ie = calloc(1, sizeof(Ecore_Idle_Enterer));
|
||||
ie = ecore_idle_enterer_calloc(1);
|
||||
if (!ie) goto unlock;
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
|
||||
ie->func = func;
|
||||
|
@ -134,7 +124,7 @@ _ecore_idle_enterer_shutdown(void)
|
|||
{
|
||||
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idle_enterer_mp_free(ie);
|
||||
}
|
||||
idle_enterers_delete_me = 0;
|
||||
idle_enterer_current = NULL;
|
||||
|
@ -190,7 +180,7 @@ _ecore_idle_enterer_call(void)
|
|||
|
||||
idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idle_enterer_mp_free(ie);
|
||||
}
|
||||
}
|
||||
if (!deleted_idler_enterers_in_use)
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
struct _Ecore_Idle_Exiter
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
static Ecore_Idle_Exiter *idle_exiters = NULL;
|
||||
static Ecore_Idle_Exiter *idle_exiter_current = NULL;
|
||||
static int idle_exiters_delete_me = 0;
|
||||
|
@ -47,7 +37,7 @@ ecore_idle_exiter_add(Ecore_Task_Cb func,
|
|||
|
||||
_ecore_lock();
|
||||
if (!func) goto unlock;
|
||||
ie = calloc(1, sizeof(Ecore_Idle_Exiter));
|
||||
ie = ecore_idle_exiter_calloc(1);
|
||||
if (!ie) goto unlock;
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
|
||||
ie->func = func;
|
||||
|
@ -102,7 +92,7 @@ _ecore_idle_exiter_shutdown(void)
|
|||
{
|
||||
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idle_exiter_mp_free(ie);
|
||||
}
|
||||
idle_exiters_delete_me = 0;
|
||||
idle_exiter_current = NULL;
|
||||
|
@ -159,7 +149,7 @@ _ecore_idle_exiter_call(void)
|
|||
|
||||
idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idle_exiter_mp_free(ie);
|
||||
}
|
||||
}
|
||||
if (!deleted_idler_exiters_in_use)
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
struct _Ecore_Idler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
static Ecore_Idler *idlers = NULL;
|
||||
static Ecore_Idler *idler_current = NULL;
|
||||
static int idlers_delete_me = 0;
|
||||
|
@ -32,7 +22,7 @@ ecore_idler_add(Ecore_Task_Cb func,
|
|||
|
||||
_ecore_lock();
|
||||
if (!func) goto unlock;
|
||||
ie = calloc(1, sizeof(Ecore_Idler));
|
||||
ie = ecore_idler_calloc(1);
|
||||
if (!ie) goto unlock;
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
|
||||
ie->func = func;
|
||||
|
@ -86,7 +76,7 @@ _ecore_idler_shutdown(void)
|
|||
{
|
||||
idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idler_mp_free(ie);
|
||||
}
|
||||
idlers_delete_me = 0;
|
||||
idler_current = NULL;
|
||||
|
@ -139,7 +129,7 @@ _ecore_idler_all_call(void)
|
|||
|
||||
idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
|
||||
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
|
||||
free(ie);
|
||||
ecore_idler_mp_free(ie);
|
||||
}
|
||||
}
|
||||
if (!deleted_idlers_in_use)
|
||||
|
|
|
@ -16,14 +16,6 @@ static void _ecore_job_event_free(void *data,
|
|||
static int ecore_event_job_type = 0;
|
||||
static Ecore_Event_Handler *_ecore_job_handler = NULL;
|
||||
|
||||
struct _Ecore_Job
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
Ecore_Event *event;
|
||||
Ecore_Cb func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
void
|
||||
_ecore_job_init(void)
|
||||
{
|
||||
|
@ -61,13 +53,13 @@ ecore_job_add(Ecore_Cb func,
|
|||
|
||||
if (!func) return NULL;
|
||||
|
||||
job = calloc(1, sizeof(Ecore_Job));
|
||||
job = ecore_job_calloc(1);
|
||||
if (!job) return NULL;
|
||||
ECORE_MAGIC_SET(job, ECORE_MAGIC_JOB);
|
||||
job->event = ecore_event_add(ecore_event_job_type, job, _ecore_job_event_free, NULL);
|
||||
if (!job->event)
|
||||
{
|
||||
free(job);
|
||||
ecore_job_mp_free(job);
|
||||
return NULL;
|
||||
}
|
||||
job->func = func;
|
||||
|
@ -115,8 +107,8 @@ _ecore_job_event_handler(void *data __UNUSED__,
|
|||
|
||||
static void
|
||||
_ecore_job_event_free(void *data __UNUSED__,
|
||||
void *ev)
|
||||
void *job)
|
||||
{
|
||||
free(ev);
|
||||
ecore_job_mp_free(job);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,42 +145,6 @@ timerfd_settime(int fd __UNUSED__,
|
|||
|
||||
#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0)
|
||||
|
||||
struct _Ecore_Fd_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Fd_Handler *next_ready;
|
||||
int fd;
|
||||
Ecore_Fd_Handler_Flags flags;
|
||||
Ecore_Fd_Cb func;
|
||||
void *data;
|
||||
Ecore_Fd_Cb buf_func;
|
||||
void *buf_data;
|
||||
Ecore_Fd_Prep_Cb prep_func;
|
||||
void *prep_data;
|
||||
int references;
|
||||
Eina_Bool read_active : 1;
|
||||
Eina_Bool write_active : 1;
|
||||
Eina_Bool error_active : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
#if defined(USE_G_MAIN_LOOP)
|
||||
GPollFD gfd;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
struct _Ecore_Win32_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
HANDLE h;
|
||||
Ecore_Win32_Handle_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef USE_G_MAIN_LOOP
|
||||
static int _ecore_main_select(double timeout);
|
||||
#endif
|
||||
|
@ -990,7 +954,7 @@ ecore_main_fd_handler_add(int fd,
|
|||
|
||||
if ((fd < 0) || (flags == 0) || (!func)) goto unlock;
|
||||
|
||||
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
|
||||
fdh = ecore_fd_handler_calloc(1);
|
||||
if (!fdh) goto unlock;
|
||||
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
|
||||
fdh->next_ready = NULL;
|
||||
|
@ -1000,7 +964,7 @@ ecore_main_fd_handler_add(int fd,
|
|||
{
|
||||
int err = errno;
|
||||
ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err));
|
||||
free(fdh);
|
||||
ecore_fd_handler_mp_free(fdh);
|
||||
fdh = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
|
@ -1033,7 +997,7 @@ ecore_main_win32_handler_add(void *h,
|
|||
|
||||
if (!h || !func) return NULL;
|
||||
|
||||
wh = calloc(1, sizeof(Ecore_Win32_Handler));
|
||||
wh = ecore_win32_handler_calloc(1);
|
||||
if (!wh) return NULL;
|
||||
ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
|
||||
wh->h = (HANDLE)h;
|
||||
|
@ -1263,7 +1227,7 @@ _ecore_main_shutdown(void)
|
|||
fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
|
||||
EINA_INLIST_GET(fdh));
|
||||
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
|
||||
free(fdh);
|
||||
ecore_fd_handler_mp_free(fdh);
|
||||
}
|
||||
if (fd_handlers_with_buffer)
|
||||
fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer);
|
||||
|
@ -1286,7 +1250,7 @@ _ecore_main_shutdown(void)
|
|||
win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
|
||||
EINA_INLIST_GET(wh));
|
||||
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
|
||||
free(wh);
|
||||
ecore_win32_handler_mp_free(wh);
|
||||
}
|
||||
win32_handlers_delete_me = EINA_FALSE;
|
||||
win32_handler_current = NULL;
|
||||
|
@ -1527,7 +1491,7 @@ _ecore_main_fd_handlers_cleanup(void)
|
|||
fd_handlers = (Ecore_Fd_Handler *)
|
||||
eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
|
||||
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
|
||||
free(fdh);
|
||||
ecore_fd_handler_mp_free(fdh);
|
||||
fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
|
||||
}
|
||||
}
|
||||
|
@ -1558,7 +1522,7 @@ _ecore_main_win32_handlers_cleanup(void)
|
|||
eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
|
||||
EINA_INLIST_GET(wh));
|
||||
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
|
||||
free(wh);
|
||||
ecore_win32_handler_mp_free(wh);
|
||||
}
|
||||
}
|
||||
if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE;
|
||||
|
|
|
@ -80,21 +80,6 @@
|
|||
|
||||
#endif /* ! _WIN32 */
|
||||
|
||||
struct _Ecore_Pipe
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
int fd_read;
|
||||
int fd_write;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
const void *data;
|
||||
Ecore_Pipe_Cb handler;
|
||||
unsigned int len;
|
||||
int handling;
|
||||
size_t already_read;
|
||||
void *passed_data;
|
||||
int message;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
static Eina_Bool _ecore_pipe_read(void *data,
|
||||
Ecore_Fd_Handler *fd_handler);
|
||||
|
@ -125,12 +110,12 @@ ecore_pipe_add(Ecore_Pipe_Cb handler,
|
|||
|
||||
if (!handler) return NULL;
|
||||
|
||||
p = (Ecore_Pipe *)calloc(1, sizeof(Ecore_Pipe));
|
||||
p = ecore_pipe_calloc(1);
|
||||
if (!p) return NULL;
|
||||
|
||||
if (pipe(fds))
|
||||
{
|
||||
free(p);
|
||||
ecore_pipe_mp_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -171,7 +156,7 @@ ecore_pipe_del(Ecore_Pipe *p)
|
|||
if (p->fd_read != PIPE_FD_INVALID) pipe_close(p->fd_read);
|
||||
if (p->fd_write != PIPE_FD_INVALID) pipe_close(p->fd_write);
|
||||
data = (void *)p->data;
|
||||
free(p);
|
||||
ecore_pipe_mp_free(p);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
struct _Ecore_Poller
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int ibit;
|
||||
unsigned char delete_me : 1;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static Ecore_Timer *timer = NULL;
|
||||
static int min_interval = -1;
|
||||
static int interval_incr = 0;
|
||||
|
@ -159,7 +149,7 @@ _ecore_poller_cb_timer(void *data __UNUSED__)
|
|||
if (poller->delete_me)
|
||||
{
|
||||
pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
|
||||
free(poller);
|
||||
ecore_poller_mp_free(poller);
|
||||
poller_delete_count--;
|
||||
changes++;
|
||||
if (poller_delete_count <= 0) break;
|
||||
|
@ -281,7 +271,7 @@ ecore_poller_add(Ecore_Poller_Type type __UNUSED__,
|
|||
if (!func) return NULL;
|
||||
if (interval < 1) interval = 1;
|
||||
|
||||
poller = calloc(1, sizeof(Ecore_Poller));
|
||||
poller = ecore_poller_calloc(1);
|
||||
if (!poller) return NULL;
|
||||
ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER);
|
||||
/* interval MUST be a power of 2, so enforce it */
|
||||
|
@ -413,7 +403,7 @@ ecore_poller_del(Ecore_Poller *poller)
|
|||
/* not in loop so safe - delete immediately */
|
||||
data = poller->data;
|
||||
pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
|
||||
free(poller);
|
||||
ecore_poller_mp_free(poller);
|
||||
_ecore_poller_next_tick_eval();
|
||||
return data;
|
||||
}
|
||||
|
@ -433,7 +423,7 @@ _ecore_poller_shutdown(void)
|
|||
while ((poller = pollers[i]))
|
||||
{
|
||||
pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
|
||||
free(poller);
|
||||
ecore_poller_mp_free(poller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,12 +79,15 @@ extern int _ecore_log_dom;
|
|||
#define ECORE_MAGIC_WIN32_HANDLER 0xf7e8f1a3
|
||||
#define ECORE_MAGIC_JOB 0x76543210
|
||||
|
||||
typedef unsigned int Ecore_Magic;
|
||||
#define ECORE_MAGIC Ecore_Magic __magic
|
||||
|
||||
#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m)
|
||||
#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
|
||||
#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
|
||||
|
||||
#include "ecore_types.h"
|
||||
|
||||
/* undef the following, we want our version */
|
||||
#undef FREE
|
||||
#define FREE(ptr) free(ptr); ptr = NULL;
|
||||
|
@ -116,8 +119,6 @@ ecore_print_warning(const char *function,
|
|||
return; \
|
||||
}
|
||||
|
||||
typedef unsigned int Ecore_Magic;
|
||||
|
||||
EAPI void _ecore_magic_fail(const void *d,
|
||||
Ecore_Magic m,
|
||||
Ecore_Magic req_m,
|
||||
|
@ -350,4 +351,26 @@ extern double _ecore_time_loop_time;
|
|||
extern Eina_Bool _ecore_glib_always_integrate;
|
||||
extern Ecore_Select_Function main_loop_select;
|
||||
|
||||
Eina_Bool ecore_mempool_init(void);
|
||||
void ecore_mempool_shutdown(void);
|
||||
#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
|
||||
TYPE *Type##_calloc(unsigned int); \
|
||||
void Type##_mp_free(TYPE *e);
|
||||
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Animator, ecore_animator);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Handler, ecore_event_handler);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Event_Filter, ecore_event_filter);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Exiter, ecore_idle_exiter);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Idle_Enterer, ecore_idle_enterer);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Idler, ecore_idler);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Job, ecore_job);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Timer, ecore_timer);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler);
|
||||
#ifdef _WIN32
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,34 +8,6 @@
|
|||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
|
||||
#ifdef WANT_ECORE_TIMER_DUMP
|
||||
# include <string.h>
|
||||
# include <execinfo.h>
|
||||
# define ECORE_TIMER_DEBUG_BT_NUM 64
|
||||
typedef void (*Ecore_Timer_Bt_Func)();
|
||||
#endif
|
||||
|
||||
struct _Ecore_Timer
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
double in;
|
||||
double at;
|
||||
double pending;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
|
||||
#ifdef WANT_ECORE_TIMER_DUMP
|
||||
Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM];
|
||||
int timer_bt_num;
|
||||
#endif
|
||||
|
||||
int references;
|
||||
unsigned char delete_me : 1;
|
||||
unsigned char just_added : 1;
|
||||
unsigned char frozen : 1;
|
||||
};
|
||||
|
||||
static void _ecore_timer_set(Ecore_Timer *timer,
|
||||
double at,
|
||||
double in,
|
||||
|
@ -140,7 +112,7 @@ ecore_timer_add(double in,
|
|||
_ecore_lock();
|
||||
if (!func) goto unlock;
|
||||
if (in < 0.0) in = 0.0;
|
||||
timer = calloc(1, sizeof(Ecore_Timer));
|
||||
timer = ecore_timer_calloc(1);
|
||||
if (!timer) goto unlock;
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
|
||||
now = ecore_time_get();
|
||||
|
@ -470,7 +442,7 @@ _ecore_timer_loop_add(double in,
|
|||
|
||||
if (!func) return timer;
|
||||
if (in < 0.0) in = 0.0;
|
||||
timer = calloc(1, sizeof(Ecore_Timer));
|
||||
timer = ecore_timer_calloc(1);
|
||||
if (!timer) return timer;
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_TIMER);
|
||||
now = ecore_loop_time_get();
|
||||
|
@ -510,7 +482,7 @@ _ecore_timer_del(Ecore_Timer *timer)
|
|||
if (timer->delete_me)
|
||||
timers_delete_me--;
|
||||
|
||||
free(timer);
|
||||
ecore_timer_mp_free(timer);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -529,14 +501,14 @@ _ecore_timer_shutdown(void)
|
|||
{
|
||||
timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers));
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
|
||||
free(timer);
|
||||
ecore_timer_mp_free(timer);
|
||||
}
|
||||
|
||||
while ((timer = suspended))
|
||||
{
|
||||
suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended));
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
|
||||
free(timer);
|
||||
ecore_timer_mp_free(timer);
|
||||
}
|
||||
|
||||
timer_current = NULL;
|
||||
|
@ -563,7 +535,7 @@ _ecore_timer_cleanup(void)
|
|||
}
|
||||
timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
|
||||
free(timer);
|
||||
ecore_timer_mp_free(timer);
|
||||
timers_delete_me--;
|
||||
done++;
|
||||
if (timers_delete_me == 0) return;
|
||||
|
@ -583,7 +555,7 @@ _ecore_timer_cleanup(void)
|
|||
}
|
||||
suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
|
||||
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
|
||||
free(timer);
|
||||
ecore_timer_mp_free(timer);
|
||||
timers_delete_me--;
|
||||
done++;
|
||||
if (timers_delete_me == 0) return;
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#ifndef ECORE_TYPES_H
|
||||
#define ECORE_TYPES_H
|
||||
|
||||
#ifdef WANT_ECORE_TIMER_DUMP
|
||||
# include <string.h>
|
||||
# include <execinfo.h>
|
||||
# define ECORE_TIMER_DEBUG_BT_NUM 64
|
||||
typedef void (*Ecore_Timer_Bt_Func)();
|
||||
#endif
|
||||
|
||||
struct _Ecore_Animator
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
|
||||
double start, run;
|
||||
Ecore_Timeline_Cb run_func;
|
||||
void *run_data;
|
||||
|
||||
Eina_Bool delete_me : 1;
|
||||
Eina_Bool suspended : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Event_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int type;
|
||||
Ecore_Event_Handler_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Event_Filter
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Data_Cb func_start;
|
||||
Ecore_Filter_Cb func_filter;
|
||||
Ecore_End_Cb func_end;
|
||||
void *loop_data;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Event
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int type;
|
||||
void *event;
|
||||
Ecore_End_Cb func_free;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Idle_Enterer
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Idle_Exiter
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Idler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Job
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
Ecore_Event *event;
|
||||
Ecore_Cb func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct _Ecore_Fd_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
Ecore_Fd_Handler *next_ready;
|
||||
int fd;
|
||||
Ecore_Fd_Handler_Flags flags;
|
||||
Ecore_Fd_Cb func;
|
||||
void *data;
|
||||
Ecore_Fd_Cb buf_func;
|
||||
void *buf_data;
|
||||
Ecore_Fd_Prep_Cb prep_func;
|
||||
void *prep_data;
|
||||
int references;
|
||||
Eina_Bool read_active : 1;
|
||||
Eina_Bool write_active : 1;
|
||||
Eina_Bool error_active : 1;
|
||||
Eina_Bool delete_me : 1;
|
||||
#if defined(USE_G_MAIN_LOOP)
|
||||
GPollFD gfd;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
struct _Ecore_Win32_Handler
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
HANDLE h;
|
||||
Ecore_Win32_Handle_Cb func;
|
||||
void *data;
|
||||
int references;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct _Ecore_Pipe
|
||||
{
|
||||
ECORE_MAGIC;
|
||||
int fd_read;
|
||||
int fd_write;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
const void *data;
|
||||
Ecore_Pipe_Cb handler;
|
||||
unsigned int len;
|
||||
int handling;
|
||||
size_t already_read;
|
||||
void *passed_data;
|
||||
int message;
|
||||
Eina_Bool delete_me : 1;
|
||||
};
|
||||
|
||||
struct _Ecore_Poller
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
int ibit;
|
||||
unsigned char delete_me : 1;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct _Ecore_Timer
|
||||
{
|
||||
EINA_INLIST;
|
||||
ECORE_MAGIC;
|
||||
double in;
|
||||
double at;
|
||||
double pending;
|
||||
Ecore_Task_Cb func;
|
||||
void *data;
|
||||
|
||||
#ifdef WANT_ECORE_TIMER_DUMP
|
||||
Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM];
|
||||
int timer_bt_num;
|
||||
#endif
|
||||
|
||||
int references;
|
||||
unsigned char delete_me : 1;
|
||||
unsigned char just_added : 1;
|
||||
unsigned char frozen : 1;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue