summaryrefslogtreecommitdiff
path: root/src/lib/eio
diff options
context:
space:
mode:
authorAl Poole <netstar@gmail.com>2017-04-28 10:16:41 -0700
committerCedric BAIL <cedric@osg.samsung.com>2017-04-28 10:17:17 -0700
commit7ee68cb4e239ac1814ceea19e5150f1645403ae4 (patch)
treec6a86e44dbf7278fa677c9e5b6dc6eccd9438153 /src/lib/eio
parent4029b99bb42079aea35642197d77e66c89ca10b5 (diff)
eio: improve Kevent (FreeBSD et. al)
Summary: Adds initial support for file/directory creation and deletion detection. Reviewers: raster, cedric Reviewed By: cedric Subscribers: raster, jpeg Differential Revision: https://phab.enlightenment.org/D4811 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/eio')
-rw-r--r--src/lib/eio/eio_monitor_kevent.c125
1 files changed, 121 insertions, 4 deletions
diff --git a/src/lib/eio/eio_monitor_kevent.c b/src/lib/eio/eio_monitor_kevent.c
index deccb34ecf..e4a6e06430 100644
--- a/src/lib/eio/eio_monitor_kevent.c
+++ b/src/lib/eio/eio_monitor_kevent.c
@@ -19,7 +19,8 @@
19 19
20#include "eio_private.h" 20#include "eio_private.h"
21#include "Eio.h" 21#include "Eio.h"
22 22#include "Eina.h"
23#include "Ecore_File.h"
23#include <sys/types.h> 24#include <sys/types.h>
24#include <sys/event.h> 25#include <sys/event.h>
25#include <sys/stat.h> 26#include <sys/stat.h>
@@ -37,32 +38,143 @@
37struct _Eio_Monitor_Backend 38struct _Eio_Monitor_Backend
38{ 39{
39 Eio_Monitor *parent; 40 Eio_Monitor *parent;
40 41 Eina_List *prev_list;
41 int fd; 42 int fd;
42}; 43};
43 44
45typedef struct _Eio_File_Info Eio_File_Info;
46struct _Eio_File_Info
47{
48 const char *path;
49 Eina_Stat st;
50};
51
44static Ecore_Fd_Handler *_kqueue_fd = NULL; 52static Ecore_Fd_Handler *_kqueue_fd = NULL;
45static Eina_Hash *_kevent_monitors = NULL; 53static Eina_Hash *_kevent_monitors = NULL;
46 54
47static void 55static void
56_eio_kevent_ls_free(Eina_List *list)
57{
58 Eio_File_Info *file;
59
60 EINA_LIST_FREE(list, file)
61 {
62 eina_stringshare_del(file->path);
63 free(file);
64 }
65}
66
67static void
48_eio_kevent_del(void *data) 68_eio_kevent_del(void *data)
49{ 69{
50 Eio_Monitor_Backend *emb = data; 70 Eio_Monitor_Backend *emb = data;
51 71
72 _eio_kevent_ls_free(emb->prev_list);
73
52 if (emb->fd) 74 if (emb->fd)
53 close(emb->fd); 75 close(emb->fd);
54 76
55 free(emb); 77 free(emb);
56} 78}
57 79
80
81static Eina_List *
82_eio_kevent_ls(const char *directory)
83{
84 Eina_Iterator *it;
85 Eina_File_Direct_Info *info;
86 Eina_List *files = NULL;
87
88 it = eina_file_direct_ls(directory);
89 if (!it) return NULL;
90
91 EINA_ITERATOR_FOREACH(it, info)
92 {
93 Eio_File_Info *file = malloc(sizeof(Eio_File_Info));
94 if (eina_file_statat(eina_iterator_container_get(it), info, &file->st))
95 {
96 free(file);
97 continue;
98 }
99 file->path = eina_stringshare_add(info->path);
100 files = eina_list_append(files, file);
101 }
102
103 return files;
104}
105
106static void
107_eio_kevent_event_find(Eio_Monitor_Backend *backend)
108{
109 Eina_List *l, *l2;
110 Eio_File_Info *file, *file2;
111 Eina_List *next_list = _eio_kevent_ls(backend->parent->path);
112
113 EINA_LIST_FOREACH(backend->prev_list, l, file)
114 {
115 Eina_Bool exists = EINA_FALSE;
116 EINA_LIST_FOREACH(next_list, l2, file2)
117 {
118 if (file->st.ino == file2->st.ino)
119 {
120 if (file->path == file2->path)
121 exists = EINA_TRUE;
122
123 if (file->st.mtime != file2->st.mtime)
124 {
125 if (S_ISDIR(file->st.mode))
126 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_DIRECTORY_MODIFIED);
127 else
128 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_FILE_MODIFIED);
129 }
130 }
131 }
132
133 if (!exists)
134 {
135 if (S_ISDIR(file->st.mode))
136 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_DIRECTORY_DELETED);
137 else
138 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_FILE_DELETED);
139 }
140 }
141
142 EINA_LIST_FOREACH(next_list, l, file)
143 {
144 Eina_Bool exists = EINA_FALSE;
145 EINA_LIST_FOREACH(backend->prev_list, l2, file2)
146 {
147 if ((file->path == file2->path) &&
148 (file->st.ino == file2->st.ino))
149 {
150 exists = EINA_TRUE;
151 break;
152 }
153 }
154
155 if (!exists)
156 {
157 if (S_ISDIR(file->st.mode))
158 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_DIRECTORY_CREATED);
159 else
160 _eio_monitor_send(backend->parent, file->path, EIO_MONITOR_FILE_CREATED);
161 }
162 }
163
164 _eio_kevent_ls_free(backend->prev_list);
165
166 backend->prev_list = next_list;
167}
168
58static Eina_Bool 169static Eina_Bool
59_eio_kevent_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh) 170_eio_kevent_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh)
60{ 171{
61 Eio_Monitor_Backend *backend; 172 Eio_Monitor_Backend *backend;
62 struct kevent evs[KEVENT_NUM_EVENTS]; 173 struct kevent evs[KEVENT_NUM_EVENTS];
63 int event_code = 0; 174 int event_code = 0;
175 const struct timespec timeout = { 0, 0 };
64 176
65 int res = kevent(ecore_main_fd_handler_fd_get(fdh), 0, 0, evs, KEVENT_NUM_EVENTS, 0); 177 int res = kevent(ecore_main_fd_handler_fd_get(fdh), 0, 0, evs, KEVENT_NUM_EVENTS, &timeout);
66 178
67 for(int i=0; i<res; ++i) 179 for(int i=0; i<res; ++i)
68 { 180 {
@@ -74,6 +186,9 @@ _eio_kevent_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fdh)
74 } 186 }
75 if(evs[i].fflags & NOTE_WRITE || evs[i].fflags & NOTE_ATTRIB) 187 if(evs[i].fflags & NOTE_WRITE || evs[i].fflags & NOTE_ATTRIB)
76 { 188 {
189 /* Handle directory/file creation and deletion */
190 _eio_kevent_event_find(backend);
191 /* Old default behaviour */
77 event_code = EIO_MONITOR_FILE_MODIFIED; 192 event_code = EIO_MONITOR_FILE_MODIFIED;
78 _eio_monitor_send(backend->parent, backend->parent->path, event_code); 193 _eio_monitor_send(backend->parent, backend->parent->path, event_code);
79 } 194 }
@@ -129,7 +244,7 @@ void eio_monitor_backend_shutdown(void)
129 fd = ecore_main_fd_handler_fd_get(_kqueue_fd); 244 fd = ecore_main_fd_handler_fd_get(_kqueue_fd);
130 ecore_main_fd_handler_del(_kqueue_fd); 245 ecore_main_fd_handler_del(_kqueue_fd);
131 _kqueue_fd = NULL; 246 _kqueue_fd = NULL;
132 247
133 if (fd < 0) 248 if (fd < 0)
134 return; 249 return;
135 250
@@ -161,6 +276,8 @@ void eio_monitor_backend_add(Eio_Monitor *monitor)
161 backend->parent = monitor; 276 backend->parent = monitor;
162 monitor->backend = backend; 277 monitor->backend = backend;
163 278
279 backend->prev_list = _eio_kevent_ls(backend->parent->path);
280
164 eina_hash_direct_add(_kevent_monitors, &backend->fd, backend); 281 eina_hash_direct_add(_kevent_monitors, &backend->fd, backend);
165 282
166 EV_SET(&e, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, 283 EV_SET(&e, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR,