3 * File System Watcher internal calls
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.
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
19 #ifdef HAVE_SYS_EVENT_H
20 #include <sys/event.h>
22 #ifdef HAVE_SYS_TIME_H
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/metadata/icall-decl.h>
31 #include <mono/utils/mono-dl.h>
32 #include <mono/utils/mono-io-portability.h>
33 #include <mono/metadata/w32error.h>
39 * We use the managed watcher on windows, so the code inside this #if is never used
42 ves_icall_System_IO_FSW_SupportsFSW (void)
48 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn
,
49 MonoStringHandleOut filename
,
51 int *reqnum
, MonoError
*error
)
58 static int (*FAMNextEvent
) (gpointer
, gpointer
);
60 #if defined(HAVE_SYS_INOTIFY_H)
61 #include <sys/inotify.h>
65 ves_icall_System_IO_FSW_SupportsFSW (void)
67 #if defined(__APPLE__)
68 if (getenv ("MONO_DARWIN_USE_KQUEUE_FSW"))
69 return 3; /* kqueue */
71 return 6; /* CoreFX */
72 #elif defined(HAVE_SYS_INOTIFY_H)
73 int inotify_instance
= inotify_init ();
74 if (inotify_instance
== -1)
75 return 0; /* DefaultWatcher */
76 close (inotify_instance
);
77 return 6; /* CoreFX */
79 return 3; /* kqueue */
82 int lib_used
= 4; /* gamin */
85 fam_module
= mono_dl_open ("libgamin-1.so", MONO_DL_LAZY
, NULL
);
86 if (fam_module
== NULL
) {
87 lib_used
= 2; /* FAM */
88 fam_module
= mono_dl_open ("libfam.so", MONO_DL_LAZY
, NULL
);
91 if (fam_module
== NULL
)
92 return 0; /* DefaultWatcher */
94 err
= mono_dl_symbol (fam_module
, "FAMNextEvent", (gpointer
*) &FAMNextEvent
);
96 if (FAMNextEvent
== NULL
)
99 return lib_used
; /* DefaultWatcher */
103 /* Almost copied from fam.h. Weird, I know */
108 typedef struct FAMEvent
{
112 gchar filename
[PATH_MAX
];
118 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn
,
119 MonoStringHandleOut filename
,
126 if (FAMNextEvent (conn
, &ev
) == 1) {
127 MONO_HANDLE_ASSIGN_RAW (filename
, mono_string_new_checked (mono_domain_get (), ev
.filename
, error
));
128 return_val_if_nok (error
, FALSE
);
130 *reqnum
= ev
.fr
.reqnum
;
141 interrupt_kevent (gpointer data
)
143 int *kq_ptr
= (int*)data
;
145 /* Interrupt the kevent () call by closing the fd */
147 /* Signal to managed code that the fd is closed */
152 * ves_icall_System_IO_KqueueMonitor_kevent_notimeout:
154 * Call kevent (), while handling runtime interruptions.
157 ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr
, gpointer changelist
, int nchanges
, gpointer eventlist
, int nevents
)
160 gboolean interrupted
;
162 mono_thread_info_install_interrupt (interrupt_kevent
, kq_ptr
, &interrupted
);
170 res
= kevent (*kq_ptr
, (const struct kevent
*)changelist
, nchanges
, (struct kevent
*)eventlist
, nevents
, NULL
);
173 mono_thread_info_uninstall_interrupt (&interrupted
);
181 ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr
, gpointer changelist
, int nchanges
, gpointer eventlist
, int nevents
)
183 g_assert_not_reached ();
187 #endif /* #if HAVE_KQUEUE */
189 #endif /* !ENABLE_NETCORE */