2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 #include <sys/types.h>
23 #ifdef HAVE_LANGINFO_H
24 # include <langinfo.h>
27 #ifdef HAVE_SYS_MMAN_H
28 # include <sys/mman.h>
37 #include "ecore_private.h"
42 #define KEEP_MAX(Global, Local) \
43 if (Global < (Local)) \
46 static int _ecore_memory_statistic(void *data);
47 static int _ecore_memory_max_total = 0;
48 static int _ecore_memory_max_free = 0;
49 static pid_t _ecore_memory_pid = 0;
52 static const char *_ecore_magic_string_get(Ecore_Magic m);
53 static int _ecore_init_count = 0;
54 int _ecore_log_dom = -1;
55 int _ecore_fps_debug = 0;
57 /** OpenBSD does not define CODESET
62 # define CODESET "INVALID"
66 * Set up connections, signal handlers, sockets etc.
67 * @return 1 or greater on success, 0 otherwise
69 * This function sets up all singal handlers and the basic event loop. If it
70 * succeeds, 1 will be returned, otherwise 0 will be returned.
75 * int main(int argc, char **argv)
79 * printf("ERROR: Cannot init Ecore!\n");
82 * ecore_main_loop_begin();
90 if (++_ecore_init_count != 1)
91 return _ecore_init_count;
94 setlocale(LC_CTYPE, "");
97 if (strcmp(nl_langinfo(CODESET), "UTF-8"))
99 WRN("Not a utf8 locale!");
104 return --_ecore_init_count;
108 _ecore_log_dom = eina_log_domain_register("Ecore",ECORE_DEFAULT_LOG_COLOR);
109 if (_ecore_log_dom < 0) {
110 EINA_LOG_ERR("Ecore was unable to create a log domain.");
111 goto shutdown_log_dom;
113 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
114 if (_ecore_fps_debug) _ecore_fps_debug_init();
115 _ecore_signal_init();
117 _ecore_thread_init();
120 _ecore_loop_time = ecore_time_get();
123 if (getenv("ECORE_MEM_STAT"))
125 _ecore_memory_pid = getpid();
126 ecore_animator_add(_ecore_memory_statistic, NULL);
130 #ifdef GLIB_INTEGRATION_ALWAYS
131 if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate();
134 return _ecore_init_count;
142 return --_ecore_init_count;
146 * Shut down connections, signal handlers sockets etc.
148 * This function shuts down all things set up in ecore_init() and cleans up all
149 * event queues, handlers, filters, timers, idlers, idle enterers/exiters
150 * etc. set up after ecore_init() was called.
152 * Do not call this function from any callback that may be called from the main
153 * loop, as the main loop will then fall over and not function properly.
158 if (--_ecore_init_count != 0)
159 return _ecore_init_count;
161 if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
162 _ecore_poller_shutdown();
163 _ecore_animator_shutdown();
164 _ecore_glib_shutdown();
165 _ecore_job_shutdown();
166 _ecore_thread_shutdown();
167 _ecore_exe_shutdown();
168 _ecore_idle_enterer_shutdown();
169 _ecore_idle_exiter_shutdown();
170 _ecore_idler_shutdown();
171 _ecore_timer_shutdown();
172 _ecore_event_shutdown();
173 _ecore_main_shutdown();
174 _ecore_signal_shutdown();
177 if (getenv("ECORE_MEM_STAT"))
179 _ecore_memory_statistic(NULL);
181 ERR("[%i] Memory MAX total: %i, free: %i",
183 _ecore_memory_max_total,
184 _ecore_memory_max_free);
188 eina_log_domain_unregister(_ecore_log_dom);
195 return _ecore_init_count;
199 ecore_print_warning(const char *function, const char *sparam)
201 WRN("***** Developer Warning ***** :\n"
202 "\tThis program is calling:\n\n"
204 "\tWith the parameter:\n\n"
206 "\tbeing NULL. Please fix your program.", function, sparam);
207 if (getenv("ECORE_ERROR_ABORT")) abort();
211 _ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
214 "*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
215 "*** IN FUNCTION: %s()", fname);
217 ERR(" Input handle pointer is NULL!");
218 else if (m == ECORE_MAGIC_NONE)
219 ERR(" Input handle has already been freed!");
221 ERR(" Input handle is wrong type\n"
222 " Expected: %08x - %s\n"
223 " Supplied: %08x - %s",
224 (unsigned int)req_m, _ecore_magic_string_get(req_m),
225 (unsigned int)m, _ecore_magic_string_get(m));
226 ERR("*** NAUGHTY PROGRAMMER!!!\n"
227 "*** SPANK SPANK SPANK!!!\n"
228 "*** Now go fix your code. Tut tut tut!");
229 if (getenv("ECORE_ERROR_ABORT")) abort();
233 _ecore_magic_string_get(Ecore_Magic m)
237 case ECORE_MAGIC_NONE:
238 return "None (Freed Object)";
240 case ECORE_MAGIC_EXE:
241 return "Ecore_Exe (Executable)";
243 case ECORE_MAGIC_TIMER:
244 return "Ecore_Timer (Timer)";
246 case ECORE_MAGIC_IDLER:
247 return "Ecore_Idler (Idler)";
249 case ECORE_MAGIC_IDLE_ENTERER:
250 return "Ecore_Idle_Enterer (Idler Enterer)";
252 case ECORE_MAGIC_IDLE_EXITER:
253 return "Ecore_Idle_Exiter (Idler Exiter)";
255 case ECORE_MAGIC_FD_HANDLER:
256 return "Ecore_Fd_Handler (Fd Handler)";
258 case ECORE_MAGIC_WIN32_HANDLER:
259 return "Ecore_Win32_Handler (Win32 Handler)";
261 case ECORE_MAGIC_EVENT_HANDLER:
262 return "Ecore_Event_Handler (Event Handler)";
264 case ECORE_MAGIC_EVENT:
265 return "Ecore_Event (Event)";
272 /* fps debug calls - for debugging how much time your app actually spends */
273 /* "running" (and the inverse being time spent running)... this does not */
274 /* account for other apps and multitasking... */
276 static int _ecore_fps_debug_init_count = 0;
277 static int _ecore_fps_debug_fd = -1;
278 unsigned int *_ecore_fps_runtime_mmap = NULL;
281 _ecore_fps_debug_init(void)
287 _ecore_fps_debug_init_count++;
288 if (_ecore_fps_debug_init_count > 1) return;
293 tmp = (char *)evil_tmpdir_get ();
294 #endif /* HAVE_EVIL */
296 snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
297 _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
298 if (_ecore_fps_debug_fd < 0)
301 _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
303 if (_ecore_fps_debug_fd >= 0)
305 unsigned int zero = 0;
306 char *buf = (char *)&zero;
307 ssize_t todo = sizeof(unsigned int);
311 ssize_t r = write(_ecore_fps_debug_fd, buf, todo);
317 else if ((r < 0) && (errno == EINTR))
321 ERR("could not write to file '%s' fd %d: %s",
322 tmp, _ecore_fps_debug_fd, strerror(errno));
323 close(_ecore_fps_debug_fd);
324 _ecore_fps_debug_fd = -1;
328 _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int),
329 PROT_READ | PROT_WRITE,
331 _ecore_fps_debug_fd, 0);
332 if (_ecore_fps_runtime_mmap == MAP_FAILED)
333 _ecore_fps_runtime_mmap = NULL;
338 _ecore_fps_debug_shutdown(void)
340 _ecore_fps_debug_init_count--;
341 if (_ecore_fps_debug_init_count > 0) return;
342 if (_ecore_fps_debug_fd >= 0)
351 tmp = (char *)evil_tmpdir_get ();
352 #endif /* HAVE_EVIL */
354 snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
356 if (_ecore_fps_runtime_mmap)
358 munmap(_ecore_fps_runtime_mmap, sizeof(int));
359 _ecore_fps_runtime_mmap = NULL;
361 close(_ecore_fps_debug_fd);
362 _ecore_fps_debug_fd = -1;
367 _ecore_fps_debug_runtime_add(double t)
369 if ((_ecore_fps_debug_fd >= 0) &&
370 (_ecore_fps_runtime_mmap))
374 tm = (unsigned int)(t * 1000000.0);
375 /* i know its not 100% theoretically guaranteed, but i'd say a write */
376 /* of an int could be considered atomic for all practical purposes */
377 /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
378 /* this can run for about 4294 seconds becore looping. if you are */
379 /* doing performance testing in one run for over an hour... well */
380 /* time to restart or handle a loop condition :) */
381 *(_ecore_fps_runtime_mmap) += tm;
387 _ecore_memory_statistic(__UNUSED__ void *data)
390 static int uordblks = 0;
391 static int fordblks = 0;
392 Eina_Bool changed = EINA_FALSE;
396 #define HAS_CHANGED(Global, Local) \
397 if (Global != Local) \
400 changed = EINA_TRUE; \
403 HAS_CHANGED(uordblks, mi.uordblks);
404 HAS_CHANGED(fordblks, mi.fordblks);
407 ERR("[%i] Memory total: %i, free: %i",
412 KEEP_MAX(_ecore_memory_max_total, mi.uordblks);
413 KEEP_MAX(_ecore_memory_max_free, mi.fordblks);