aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/efreet
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-23 11:59:37 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-08-23 12:04:06 +0900
commit561f8eaa8faebe32b9a03cf9674c147cf0d6d9ab (patch)
tree150e42dcb87333b146e884f6bf72dc5f561e7967 /src/bin/efreet
parentefreet - fix efreet_*_dir_get() to support the xdg env vars (diff)
downloadefl-561f8eaa8faebe32b9a03cf9674c147cf0d6d9ab.tar.gz
efreet - save about 240-300k or so of memory used by efreet mime
so efreet mime was loading a bunch of mime type info files, parsing them on startup and allocating memory to store all this mime info - globs, mimetype strings and more. all a big waste of memory as its allocated on the heap per process where its the SAME data files loaded every time. so make an efreet mime cache file and a tool to create it from mime files. mmap this file with all the hashes/strings in it so all that data is mmaped once in memory and shared between all processes and it is only paged in on demand - as actually read/needed so if your process doesnt need to know about mime stuff.. it wont touch it anyway. this saves about 240-300k or so of memory in my tests. this has not covered the mime MAGIC files which still consume memory and are on the heap. this is more complex so it will take more time to come up with a nice file format for the data that is nicely mmaped etc. @optimize
Diffstat (limited to 'src/bin/efreet')
-rw-r--r--src/bin/efreet/.gitignore1
-rw-r--r--src/bin/efreet/efreet_mime_cache_create.c453
-rw-r--r--src/bin/efreet/efreetd_cache.c124
-rw-r--r--src/bin/efreet/efreetd_ipc.c6
-rw-r--r--src/bin/efreet/efreetd_ipc.h1
5 files changed, 585 insertions, 0 deletions
diff --git a/src/bin/efreet/.gitignore b/src/bin/efreet/.gitignore
index 76fc57659f..f6ff3d04e7 100644
--- a/src/bin/efreet/.gitignore
+++ b/src/bin/efreet/.gitignore
@@ -1,3 +1,4 @@
/efreet_desktop_cache_create
/efreet_icon_cache_create
/efreetd
+/efreet_mime_cache_create
diff --git a/src/bin/efreet/efreet_mime_cache_create.c b/src/bin/efreet/efreet_mime_cache_create.c
new file mode 100644
index 0000000000..8f8b0a1f88
--- /dev/null
+++ b/src/bin/efreet/efreet_mime_cache_create.c
@@ -0,0 +1,453 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#ifdef _WIN32
+# include <winsock2.h>
+#endif
+#include <libgen.h>
+#include <ctype.h>
+
+#include <Eina.h>
+#include <Eet.h>
+#include <Ecore.h>
+#include <Ecore_File.h>
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#define EFREET_MODULE_LOG_DOM _efreet_mime_cache_log_dom
+static int _efreet_mime_cache_log_dom = -1;
+static Eina_List *extra_dirs = NULL;
+
+static Eina_Hash *mimes = NULL;
+static Eina_Hash *extn_mimes = NULL;
+static Eina_Hash *glob_mimes = NULL;
+static Eina_List *mimes_sorted = NULL;
+static Eina_List *extn_mimes_sorted = NULL;
+static Eina_List *glob_mimes_sorted = NULL;
+
+#include "Efreet.h"
+#include "efreet_private.h"
+#include "efreet_cache_private.h"
+
+static int
+cache_lock_file(void)
+{
+ char file[PATH_MAX];
+ struct flock fl;
+ int lockfd;
+
+ snprintf(file, sizeof(file), "%s/efreet/mime_data.lock", efreet_cache_home_get());
+ lockfd = open(file, O_CREAT | O_BINARY | O_RDWR, S_IRUSR | S_IWUSR);
+ if (lockfd < 0) return -1;
+ efreet_fsetowner(lockfd);
+
+ memset(&fl, 0, sizeof(struct flock));
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ if (fcntl(lockfd, F_SETLK, &fl) < 0)
+ {
+ INF("LOCKED! You may want to delete %s if this persists", file);
+ close(lockfd);
+ return -1;
+ }
+
+ return lockfd;
+}
+
+static int
+hash_list_sort_insert_cmp(const char *key1, const char *key2)
+{
+ return strcmp(key1, key2);
+}
+
+static Eina_Bool
+hash_list_sort_each(const Eina_Hash *hash EINA_UNUSED, const void *key, void *value EINA_UNUSED, void *data)
+{
+ Eina_List **list = data;
+ *list = eina_list_sorted_insert(*list,
+ EINA_COMPARE_CB(hash_list_sort_insert_cmp),
+ key);
+ return EINA_TRUE;
+}
+
+static void
+hash_list_sort(Eina_Hash *hash, Eina_List **list)
+{
+ eina_hash_foreach(hash, hash_list_sort_each, list);
+}
+
+static void
+etc_mime_types_load(const char *file)
+{
+ int len;
+ char buf[4096], buf2[4096], buf3[4096], *p, *p2;
+ const char *mime;
+ FILE *f = fopen(file, "r");
+
+ if (!f) return;
+ while (fgets(buf, sizeof(buf), f))
+ {
+ // remove newline at end of line string if there
+ buf[sizeof(buf) - 1] = 0;
+ len = strlen(buf);
+ if ((len > 0) && (buf[len - 1] == '\n')) buf[len - 1] = 0;
+ // buf: "# comment"
+ // or
+ // buf: "mime/type"
+ // buf: "mime/type "
+ // buf: "mime/type ext1"
+ // buf: "mime/type ext1 ext2"
+ // buf: "mime/type ext1 ext2 ext3"
+ // ...
+ p = buf;
+ // find first token in line
+ while ((*p) && isspace(*p)) p++;
+ // if comment - skip line
+ if (*p == '#') continue;
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // token is between p and p2 (not including p2)
+ strncpy(buf2, p, p2 - p);
+ buf2[p2 - p] = 0;
+ mime = eina_stringshare_add(buf2);
+ // buf2 is now the mime type token
+ eina_hash_del(mimes, buf2, NULL);
+ eina_hash_add(mimes, buf2, mime);
+ // now lookf for all extension tokens;
+ p = p2;
+ // find next token in line
+ while ((*p) && isspace(*p)) p++;
+ while (*p)
+ {
+ // find end of token
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // buf3 is now the extension token
+ strncpy(buf3, p, p2 - p);
+ buf3[p2 - p] = 0;
+ eina_hash_del(extn_mimes, buf3, NULL);
+ eina_hash_add(extn_mimes, buf3, mime);
+ // go to next token if any
+ p = p2;
+ while ((*p) && isspace(*p)) p++;
+ }
+ }
+ fclose(f);
+}
+
+static void
+share_mime_globs_load(const char *file)
+{
+ int len;
+ char buf[4096], buf2[4096], buf3[4096], *p, *p2;
+ const char *mime;
+ FILE *f = fopen(file, "r");
+
+ if (!f) return;
+ while (fgets(buf, sizeof(buf), f))
+ {
+ // remove newline at end of line string if there
+ buf[sizeof(buf) - 1] = 0;
+ len = strlen(buf);
+ if ((len > 0) && (buf[len - 1] == '\n')) buf[len - 1] = 0;
+ // buf: "# comment"
+ // or
+ // buf: "mime/type:glob"
+ // ...
+ p = buf;
+ // find first token in line
+ while ((*p) && isspace(*p)) p++;
+ // if comment - skip line
+ if (*p == '#') continue;
+ p2 = p;
+ while ((*p2) && (*p2 != ':')) p2++;
+ // token is between p and p2 (not including p2)
+ strncpy(buf2, p, p2 - p);
+ buf2[p2 - p] = 0;
+ mime = eina_stringshare_add(buf2);
+ // buf2 is now the mime type token
+ eina_hash_del(mimes, buf2, NULL);
+ eina_hash_add(mimes, buf2, mime);
+ // now lookf for all extension tokens;
+ p = p2;
+ // find next token in line
+ while ((*p) && (*p == ':')) p++;
+ // find end of token
+ p2 = p;
+ while ((*p2) && !isspace(*p2)) p2++;
+ // buf3 is now the extension token
+ strncpy(buf3, p, p2 - p);
+ buf3[p2 - p] = 0;
+ // for a shortcut a glob of "*.xxx" is the same as just an ext of "xxx"
+ // so if this is the case then put into the extn mimes not
+ // the globl mimes for speed of lookup later on
+ if ((buf3[0] == '*') && (buf3[1] == '.') &&
+ (!strchr(buf3 + 2, '*')) && (!strchr(buf3 + 2, '?')) &&
+ (!strchr(buf3 + 2, '[')) && (!strchr(buf3 + 2, ']')) &&
+ (!strchr(buf3 + 2, '\\')))
+ {
+ eina_hash_del(extn_mimes, buf3 + 2, NULL);
+ eina_hash_add(extn_mimes, buf3 + 2, mime);
+ }
+ else
+ {
+ eina_hash_del(glob_mimes, buf3, NULL);
+ eina_hash_add(glob_mimes, buf3, mime);
+ }
+ }
+ fclose(f);
+}
+
+static void *
+find_off(const char *str, Eina_List *strlist, Eina_List *offlist)
+{
+ Eina_List *l, *ll;
+ const char *s;
+
+ ll = offlist;
+ EINA_LIST_FOREACH(strlist, l, s)
+ {
+ if (!strcmp(str, s)) return ll->data;
+ ll = ll->next;
+ }
+ return (void *)-1;
+}
+static void
+store_cache(const char *out)
+{
+ char buf[PATH_MAX];
+ FILE *f;
+ size_t mimes_str_len = 0;
+ size_t extn_mimes_str_len = 0;
+ size_t glob_mimes_str_len = 0;
+ size_t str_start;
+ Eina_List *mimes_str_offsets = NULL;
+ Eina_List *extn_mimes_str_offsets = NULL;
+ Eina_List *glob_mimes_str_offsets = NULL;
+ Eina_List *l, *ll;
+ const char *s;
+ void *ptr;
+ unsigned int val;
+
+ snprintf(buf, sizeof(buf), "%s.tmp", out);
+ f = fopen(buf, "wb");
+ if (!f) return;
+ // write file magic - first 16 bytes
+ fwrite("EfrEeT-MiMeS-001", 16, 1, f);
+ // note: all offsets are in bytes from start of file
+ //
+ // "EfrEeT-MiMeS-001" <- magic 16 byte header
+ // [int] <- size of mimes array in number of entries
+ // [int] <- str byte offset of 1st mime string (sorted)
+ // [int] <- str byte offset of 2nd mime string
+ // ...
+ // [int] <- size of extn_mimes array in number of entries
+ // [int] <- str byte offset of 1st extn string (sorted)
+ // [int] <- str byte offset of 1st mime string
+ // [int] <- str byte offset of 2nd extn string
+ // [int] <- str byte offset of 2nd mine string
+ // ...
+ // [int] <- size of globs array in number of entries
+ // [int] <- str byte offset of 1st glob string (sorted)
+ // [int] <- str byte offset of 1st mime string
+ // [int] <- str byte offset of 2nd glob string
+ // [int] <- str byte offset of 2nd mime string
+ // ...
+ // strine1\0string2\0string3\0string4\0....
+ EINA_LIST_FOREACH(mimes_sorted, l, s)
+ {
+ mimes_str_offsets = eina_list_append(mimes_str_offsets,
+ (void *)mimes_str_len);
+ mimes_str_len += strlen(s) + 1;
+ }
+ EINA_LIST_FOREACH(extn_mimes_sorted, l, s)
+ {
+ extn_mimes_str_offsets = eina_list_append(extn_mimes_str_offsets,
+ (void *)extn_mimes_str_len);
+ extn_mimes_str_len += strlen(s) + 1;
+ }
+ EINA_LIST_FOREACH(glob_mimes_sorted, l, s)
+ {
+ glob_mimes_str_offsets = eina_list_append(glob_mimes_str_offsets,
+ (void *)glob_mimes_str_len);
+ glob_mimes_str_len += strlen(s) + 1;
+ }
+
+ str_start = 16 + // magic header
+ sizeof(int) +
+ (eina_list_count(mimes_sorted) * sizeof(int)) +
+ sizeof(int) +
+ (eina_list_count(extn_mimes_sorted) * sizeof(int) * 2) +
+ sizeof(int) +
+ (eina_list_count(glob_mimes_sorted) * sizeof(int) * 2);
+
+ val = eina_list_count(mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ EINA_LIST_FOREACH(mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ }
+
+ val = eina_list_count(extn_mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ ll = extn_mimes_sorted;
+ EINA_LIST_FOREACH(extn_mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start + mimes_str_len;
+ fwrite(&val, sizeof(val), 1, f);
+ s = eina_hash_find(extn_mimes, ll->data);
+ ptr = find_off(s, mimes_sorted, mimes_str_offsets);
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ ll = ll->next;
+ }
+
+ val = eina_list_count(glob_mimes_sorted);
+ fwrite(&val, sizeof(val), 1, f);
+ ll = glob_mimes_sorted;
+ EINA_LIST_FOREACH(glob_mimes_str_offsets, l, ptr)
+ {
+ val = (int)((long)ptr) + str_start + mimes_str_len + extn_mimes_str_len;
+ fwrite(&val, sizeof(val), 1, f);
+ s = eina_hash_find(glob_mimes, ll->data);
+ ptr = find_off(s, mimes_sorted, mimes_str_offsets);
+ val = (int)((long)ptr) + str_start;
+ fwrite(&val, sizeof(val), 1, f);
+ ll = ll->next;
+ }
+ EINA_LIST_FOREACH(mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ EINA_LIST_FOREACH(extn_mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ EINA_LIST_FOREACH(glob_mimes_sorted, l, s)
+ {
+ fwrite(s, strlen(s) + 1, 1, f);
+ }
+ fclose(f);
+ rename(buf, out);
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[PATH_MAX];
+ const char *s;
+ int i;
+ int ret = -1, lockfd = -1;
+ Eina_List *datadirs, *l;
+
+ if (!eina_init()) goto eina_error;
+ if (!eet_init()) goto eet_error;
+ if (!ecore_init()) goto ecore_error;
+ if (!ecore_file_init()) goto ecore_file_error;
+ if (!efreet_init()) goto efreet_error;
+
+ _efreet_mime_cache_log_dom =
+ eina_log_domain_register("efreet_mime_cache", EFREET_DEFAULT_LOG_COLOR);
+ if (_efreet_mime_cache_log_dom < 0)
+ {
+ EINA_LOG_ERR("Efreet: Could not create a log domain for efreet_mime_cache.");
+ return -1;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], "-v"))
+ eina_log_domain_level_set("efreet_mime_cache", EINA_LOG_LEVEL_DBG);
+ else if ((!strcmp(argv[i], "-h")) ||
+ (!strcmp(argv[i], "-help")) ||
+ (!strcmp(argv[i], "--h")) ||
+ (!strcmp(argv[i], "--help")))
+ {
+ printf("Options:\n");
+ printf(" -v Verbose mode\n");
+ printf(" -d dir1 dir2 Extra dirs\n");
+ exit(0);
+ }
+ else if (!strcmp(argv[i], "-d"))
+ {
+ while ((i < (argc - 1)) && (argv[(i + 1)][0] != '-'))
+ extra_dirs = eina_list_append(extra_dirs, argv[++i]);
+ }
+ }
+ extra_dirs = eina_list_sort(extra_dirs, -1, EINA_COMPARE_CB(strcmp));
+
+ /* create homedir */
+ snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
+ if (!ecore_file_exists(buf))
+ {
+ if (!ecore_file_mkpath(buf)) goto error;
+ efreet_setowner(buf);
+ }
+
+ /* lock process, so that we only run one copy of this program */
+ lockfd = cache_lock_file();
+ if (lockfd == -1) goto error;
+
+ mimes = eina_hash_string_superfast_new(NULL);
+ extn_mimes = eina_hash_string_superfast_new(NULL);
+ glob_mimes = eina_hash_string_superfast_new(NULL);
+
+ etc_mime_types_load("/etc/mime.types");
+ share_mime_globs_load("/usr/share/mime/globs");
+ datadirs = efreet_data_dirs_get();
+ EINA_LIST_FOREACH(datadirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ share_mime_globs_load(buf);
+ }
+ EINA_LIST_FOREACH(extra_dirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ share_mime_globs_load(buf);
+ }
+ snprintf(buf, sizeof(buf), "%s/mime/globs", efreet_data_home_get());
+ share_mime_globs_load(buf);
+ // XXX: load user files and other dirs etc.
+ // XXX: load globs
+
+ hash_list_sort(mimes, &mimes_sorted);
+ hash_list_sort(extn_mimes, &extn_mimes_sorted);
+ hash_list_sort(glob_mimes, &glob_mimes_sorted);
+
+#ifdef WORDS_BIGENDIAN
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.be.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#else
+ snprintf(buf, sizeof(buf), "%s/efreet/mime_cache_%s.le.dat",
+ efreet_cache_home_get(), efreet_hostname_get());
+#endif
+ store_cache(buf);
+
+ ret = 0;
+ close(lockfd);
+error:
+ efreet_shutdown();
+efreet_error:
+ ecore_file_shutdown();
+ecore_file_error:
+ ecore_shutdown();
+ecore_error:
+ eet_shutdown();
+eet_error:
+ eina_list_free(extra_dirs);
+ eina_log_domain_unregister(_efreet_mime_cache_log_dom);
+ eina_shutdown();
+eina_error:
+ return ret;
+}
diff --git a/src/bin/efreet/efreetd_cache.c b/src/bin/efreet/efreetd_cache.c
index fefc852dd0..b1ef5e8b81 100644
--- a/src/bin/efreet/efreetd_cache.c
+++ b/src/bin/efreet/efreetd_cache.c
@@ -71,6 +71,13 @@ static Eet_Data_Descriptor *subdir_dir_edd = NULL;
static Subdir_Cache *subdir_cache = NULL;
static Eina_Bool subdir_need_save = EINA_FALSE;
+static Eina_Hash *mime_monitors = NULL;
+static Ecore_Timer *mime_update_timer = NULL;
+static Ecore_Exe *mime_cache_exe = NULL;
+
+static void mime_cache_init(void);
+static void mime_cache_shutdown(void);
+
static void
subdir_cache_dir_free(Subdir_Cache_Dir *cd)
{
@@ -756,6 +763,10 @@ cache_exe_data_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
if ((ev->lines) && (*ev->lines->line == 'c')) update = EINA_TRUE;
send_signal_icon_cache_update(update);
}
+ else if (ev->exe == mime_cache_exe)
+ {
+ // XXX: ZZZ: handle stdout here from cache updater... if needed
+ }
return ECORE_CALLBACK_RENEW;
}
@@ -774,6 +785,11 @@ cache_exe_del_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
icon_cache_exe = NULL;
if (icon_queue) cache_icon_update(EINA_FALSE);
}
+ else if (ev->exe == mime_cache_exe)
+ {
+ mime_cache_exe = NULL;
+ send_signal_mime_cache_build();
+ }
return ECORE_CALLBACK_RENEW;
}
@@ -838,6 +854,111 @@ cache_desktop_exists(void)
return desktop_exists;
}
+static void
+mime_update_launch(void)
+{
+ char file[PATH_MAX];
+
+ snprintf(file, sizeof(file),
+ "%s/efreet/" MODULE_ARCH "/efreet_mime_cache_create",
+ eina_prefix_lib_get(pfx));
+ mime_cache_exe = ecore_exe_pipe_run(file,
+ ECORE_EXE_PIPE_READ |
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED,
+ NULL);
+}
+
+static Eina_Bool
+mime_update_cache_cb(void *data EINA_UNUSED)
+{
+ mime_update_timer = NULL;
+ if (mime_cache_exe)
+ {
+ ecore_exe_kill(mime_cache_exe);
+ ecore_exe_free(mime_cache_exe);
+ }
+ mime_update_launch();
+ return EINA_FALSE;
+}
+
+static void
+mime_changes_cb(void *data EINA_UNUSED, Ecore_File_Monitor *em EINA_UNUSED,
+ Ecore_File_Event event, const char *path EINA_UNUSED)
+{
+ switch (event)
+ {
+ case ECORE_FILE_EVENT_NONE:
+ /* noop */
+ break;
+
+ case ECORE_FILE_EVENT_CREATED_FILE:
+ case ECORE_FILE_EVENT_DELETED_FILE:
+ case ECORE_FILE_EVENT_MODIFIED:
+ case ECORE_FILE_EVENT_CLOSED:
+ case ECORE_FILE_EVENT_DELETED_DIRECTORY:
+ case ECORE_FILE_EVENT_CREATED_DIRECTORY:
+ case ECORE_FILE_EVENT_DELETED_SELF:
+ mime_cache_shutdown();
+ mime_cache_init();
+ if (mime_update_timer) ecore_timer_del(mime_update_timer);
+ mime_update_timer = ecore_timer_add(0.2, mime_update_cache_cb, NULL);
+ break;
+ }
+}
+
+static void
+mime_cache_init(void)
+{
+ Ecore_File_Monitor *mon;
+ Eina_List *datadirs, *l;
+ const char *s;
+ char buf[PATH_MAX];
+
+ mime_monitors = eina_hash_string_superfast_new(NULL);
+
+ mon = ecore_file_monitor_add("/etc/mime.types", mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, "/etc/mime.types", mon);
+ mon = ecore_file_monitor_add("/usr/share/mime/globs", mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, "/usr/share/mime/globs", mon);
+
+ datadirs = efreet_data_dirs_get();
+ EINA_LIST_FOREACH(datadirs, l, s)
+ {
+ snprintf(buf, sizeof(buf), "%s/mime/globs", s);
+ if (!eina_hash_find(mime_monitors, buf))
+ {
+ mon = ecore_file_monitor_add(buf, mime_changes_cb, NULL);
+ if (mon) eina_hash_add(mime_monitors, buf, mon);
+ }
+ }
+}
+
+static Eina_Bool
+mime_cache_monitor_del(const Eina_Hash *hash EINA_UNUSED,
+ const void *key EINA_UNUSED, void *value,
+ void *data EINA_UNUSED)
+{
+ Ecore_File_Monitor *mon = value;
+ ecore_file_monitor_del(mon);
+ return EINA_TRUE;
+}
+
+static void
+mime_cache_shutdown(void)
+{
+ if (mime_update_timer)
+ {
+ ecore_timer_del(mime_update_timer);
+ mime_update_timer = NULL;
+ }
+ if (mime_monitors)
+ {
+ eina_hash_foreach(mime_monitors, mime_cache_monitor_del, NULL);
+ eina_hash_free(mime_monitors);
+ mime_monitors = NULL;
+ }
+}
+
Eina_Bool
cache_init(void)
{
@@ -875,6 +996,8 @@ cache_init(void)
efreet_cache_update = 0;
if (!efreet_init()) goto error;
subdir_cache_init();
+ mime_cache_init();
+ mime_update_launch();
read_lists();
/* TODO: Should check if system dirs has changed and handles extra_dirs */
desktop_system_dirs = efreet_default_dirs_get(efreet_data_home_get(),
@@ -906,6 +1029,7 @@ cache_shutdown(void)
eina_prefix_free(pfx);
pfx = NULL;
+ mime_cache_shutdown();
subdir_cache_shutdown();
efreet_shutdown();
diff --git a/src/bin/efreet/efreetd_ipc.c b/src/bin/efreet/efreetd_ipc.c
index 2c483c5a79..533a33bc75 100644
--- a/src/bin/efreet/efreetd_ipc.c
+++ b/src/bin/efreet/efreetd_ipc.c
@@ -190,6 +190,12 @@ send_signal_desktop_cache_build(void)
_broadcast(ipc, 1 /* desktop cache build */, 1, NULL, 0);
}
+void
+send_signal_mime_cache_build(void)
+{
+ _broadcast(ipc, 4 /* mime cache build */, 1, NULL, 0);
+}
+
Eina_Bool
ipc_init(void)
{
diff --git a/src/bin/efreet/efreetd_ipc.h b/src/bin/efreet/efreetd_ipc.h
index 6508f8f7b4..e2b3b5abf1 100644
--- a/src/bin/efreet/efreetd_ipc.h
+++ b/src/bin/efreet/efreetd_ipc.h
@@ -4,6 +4,7 @@
void send_signal_icon_cache_update(Eina_Bool update);
void send_signal_desktop_cache_update(Eina_Bool update);
void send_signal_desktop_cache_build(void);
+void send_signal_mime_cache_build(void);
Eina_Bool ipc_init(void);
Eina_Bool ipc_shutdown(void);