2 * servicedir_listener.c
4 * Created on: Sep 25, 2010
12 #include <sys/types.h>
13 #include <sys/inotify.h>
21 #include "servicedir_listener.h"
23 static pthread_t _listener_thread;
24 static bool _listener_stop_requested;
25 static bool _listener_running = false;
26 static int _dir_handle = -1;
27 static int _inotify_handle = -1;
28 static pthread_mutex_t _listener_mutex;
30 static void init_servicedir_listener() {
31 //_listener_mutex = PTHREAD_MUTEX_INITIALIZER;
32 pthread_mutex_init(&_listener_mutex, NULL);
35 static void deinit_servicedir_listener() {
36 pthread_mutex_destroy(&_listener_mutex);
39 static void *servicedir_listener_thread(void *thread_args_pointer)
44 struct inotify_event *event;
48 * Size of each i-notify event read: size of event structure + filename length that caused the event. (name follows the struct).
49 * We create a buffer that could in theory handle 16 events for files which name would be in maximum 1024 chars. (=CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE)
51 buffer_max_size = CONST_MAX_INOTIFY_EVENT_COUNT_READ * (sizeof(struct inotify_event) + CONST_MAX_EXPECTED_INOTIFY_EVENT_SIZE);
52 buffer = calloc(1, buffer_max_size);
54 _inotify_handle = inotify_init();
55 if (_inotify_handle >= 0) {
56 _dir_handle = inotify_add_watch(_inotify_handle,
57 CONST_SERVICE_DIRECTORY_LOCATION,
58 IN_CREATE | IN_ATTRIB | IN_MODIFY | IN_DELETE);
59 if (_dir_handle >= 0) {
60 log_info("Waiting service directory file events\n");
61 while (_listener_stop_requested == false) {
63 log_debug("Waiting service directory file event\n");
64 b_count = read(_inotify_handle,
67 log_debug("Service directory file event received\n");
69 while (ii < b_count) {
70 event = (struct inotify_event *)&buffer[ii];
71 log_debug("event length = %d\n", event->len);
73 if (event->mask & IN_CREATE) {
74 if ((event->mask & IN_ISDIR) == 0) {
75 log_info("file create event: %s\n", event->name);
78 log_debug("sub-directory create event: %s, no need to process\n", event->name);
81 else if (event->mask & IN_ATTRIB) {
82 if ((event->mask & IN_ISDIR) == 0) {
83 log_info("file attribute change event: %s\n", event->name);
86 log_debug("sub-directory attribute change event: %s, no need to process\n", event->name);
89 else if (event->mask & IN_MODIFY) {
90 if ((event->mask & IN_ISDIR) == 0) {
91 log_info("file modify event: %s\n", event->name);
94 log_debug("sub-directory modify event: %s, no need to process\n", event->name);
97 else if (event->mask & IN_DELETE) {
98 if ((event->mask & IN_ISDIR) == 0) {
99 log_info("file delete event: %s\n", event->name);
102 log_debug("sub-directory delete event: %s, no need to process\n", event->name);
106 ii = ii + sizeof(struct inotify_event) + event->len;
110 log_error("Failed to initialize service directory listener: %s, event read failed.\n", CONST_SERVICE_DIRECTORY_LOCATION);
113 log_info("Closing service directory listener: %s, close request received.\n", CONST_SERVICE_DIRECTORY_LOCATION);
114 pthread_mutex_lock(&_listener_mutex);
115 if ((_inotify_handle > 0) && (_dir_handle)) {
116 inotify_rm_watch(_inotify_handle, _dir_handle);
119 pthread_mutex_unlock(&_listener_mutex);
122 log_error("Failed to initialize service directory listener: %s, event listener start-up error.\n", CONST_SERVICE_DIRECTORY_LOCATION);
124 pthread_mutex_lock(&_listener_mutex);
125 if (_inotify_handle > 0) {
126 close(_inotify_handle);
127 _inotify_handle = -1;
129 pthread_mutex_unlock(&_listener_mutex);
132 log_error("Failed to initialize service directory listener: %s\n", CONST_SERVICE_DIRECTORY_LOCATION);
134 if (buffer != NULL) {
140 log_error("Failed to initialize service directory listener: %s, buffer allocation error.\n", CONST_SERVICE_DIRECTORY_LOCATION);
142 _listener_running = false;
146 void start_servicedir_listener() {
147 log_debug("listen_closed_processes()\n");
148 init_servicedir_listener();
149 if (_listener_running == false) {
150 _listener_thread = 0;
151 _listener_stop_requested = false;
152 _listener_running = true;
153 pthread_create(&_listener_thread,
155 servicedir_listener_thread,
160 void stop_servicedir_listener() {
161 _listener_stop_requested = true;
162 pthread_mutex_lock(&_listener_mutex);
163 if ((_inotify_handle > 0) && (_dir_handle)) {
164 inotify_rm_watch(_inotify_handle, _dir_handle);
165 close(_inotify_handle);
167 _inotify_handle = -1;
169 pthread_mutex_unlock(&_listener_mutex);
170 pthread_join(_listener_thread, NULL);
171 deinit_servicedir_listener();