[runtime] Rename most System.Reflection.MonoX classes to RuntimeX for consistency...
[mono-project.git] / mono / metadata / filewatcher.c
blobc472b1a45cec32dcc10a56845119666602f79e61
1 /**
2 * \file
3 * File System Watcher internal calls
5 * Authors:
6 * Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #ifdef HAVE_CONFIG_H
13 #include <config.h>
14 #endif
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19 #ifdef HAVE_SYS_EVENT_H
20 #include <sys/event.h>
21 #endif
22 #ifdef HAVE_SYS_TIME_H
23 #include <sys/time.h>
24 #endif
26 #include <mono/metadata/appdomain.h>
27 #include <mono/metadata/exception.h>
28 #include <mono/metadata/filewatcher.h>
29 #include <mono/metadata/marshal.h>
30 #include <mono/utils/mono-dl.h>
31 #include <mono/utils/mono-io-portability.h>
32 #include <mono/metadata/w32error.h>
34 #ifdef HOST_WIN32
37 * TODO:
38 * We use the managed watcher on windows, so the code inside this #if is never used
40 gint
41 ves_icall_System_IO_FSW_SupportsFSW (void)
43 return 1;
46 gboolean
47 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
48 MonoString **filename,
49 gint *code,
50 gint *reqnum)
52 return FALSE;
55 #else
57 static int (*FAMNextEvent) (gpointer, gpointer);
59 gint
60 ves_icall_System_IO_FSW_SupportsFSW (void)
62 #if defined(__APPLE__)
63 if (getenv ("MONO_DARWIN_USE_KQUEUE_FSW"))
64 return 3; /* kqueue */
65 else
66 return 6; /* CoreFX */
67 #elif defined(HAVE_SYS_INOTIFY_H)
68 return 6; /* CoreFX */
69 #elif HAVE_KQUEUE
70 return 3; /* kqueue */
71 #else
72 MonoDl *fam_module;
73 int lib_used = 4; /* gamin */
74 char *err;
76 fam_module = mono_dl_open ("libgamin-1.so", MONO_DL_LAZY, NULL);
77 if (fam_module == NULL) {
78 lib_used = 2; /* FAM */
79 fam_module = mono_dl_open ("libfam.so", MONO_DL_LAZY, NULL);
82 if (fam_module == NULL)
83 return 0; /* DefaultWatcher */
85 err = mono_dl_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
86 g_free (err);
87 if (FAMNextEvent == NULL)
88 return 0;
90 return lib_used; /* DefaultWatcher */
91 #endif
94 /* Almost copied from fam.h. Weird, I know */
95 typedef struct {
96 gint reqnum;
97 } FAMRequest;
99 typedef struct FAMEvent {
100 gpointer fc;
101 FAMRequest fr;
102 gchar *hostname;
103 gchar filename [PATH_MAX];
104 gpointer userdata;
105 gint code;
106 } FAMEvent;
108 gboolean
109 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
110 MonoString **filename,
111 gint *code,
112 gint *reqnum)
114 ERROR_DECL (error);
115 FAMEvent ev;
117 if (FAMNextEvent (conn, &ev) == 1) {
118 *filename = mono_string_new_checked (mono_domain_get (), ev.filename, error);
119 *code = ev.code;
120 *reqnum = ev.fr.reqnum;
121 if (mono_error_set_pending_exception (error))
122 return FALSE;
123 return TRUE;
126 return FALSE;
128 #endif
130 #if HAVE_KQUEUE
132 static void
133 interrupt_kevent (gpointer data)
135 int *kq_ptr = (int*)data;
137 /* Interrupt the kevent () call by closing the fd */
138 close (*kq_ptr);
139 /* Signal to managed code that the fd is closed */
140 *kq_ptr = -1;
144 * ves_icall_System_IO_KqueueMonitor_kevent_notimeout:
146 * Call kevent (), while handling runtime interruptions.
149 ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
151 int res;
152 gboolean interrupted;
154 mono_thread_info_install_interrupt (interrupt_kevent, kq_ptr, &interrupted);
155 if (interrupted) {
156 close (*kq_ptr);
157 *kq_ptr = -1;
158 return -1;
161 MONO_ENTER_GC_SAFE;
162 res = kevent (*kq_ptr, (const struct kevent*)changelist, nchanges, (struct kevent*)eventlist, nevents, NULL);
163 MONO_EXIT_GC_SAFE;
165 mono_thread_info_uninstall_interrupt (&interrupted);
167 return res;
170 #else
173 ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
175 g_assert_not_reached ();
176 return -1;
179 #endif /* #if HAVE_KQUEUE */