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/utils/mono-dl.h>
31 #include <mono/utils/mono-io-portability.h>
32 #include <mono/metadata/w32error.h>
38 * We use the managed watcher on windows, so the code inside this #if is never used
41 ves_icall_System_IO_FSW_SupportsFSW (void)
47 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn
,
48 MonoString
**filename
,
57 static int (*FAMNextEvent
) (gpointer
, gpointer
);
60 ves_icall_System_IO_FSW_SupportsFSW (void)
62 #if defined(__APPLE__)
63 if (getenv ("MONO_DARWIN_USE_KQUEUE_FSW"))
64 return 3; /* kqueue */
66 return 6; /* CoreFX */
67 #elif defined(HAVE_SYS_INOTIFY_H)
68 return 6; /* CoreFX */
70 return 3; /* kqueue */
73 int lib_used
= 4; /* gamin */
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
);
87 if (FAMNextEvent
== NULL
)
90 return lib_used
; /* DefaultWatcher */
94 /* Almost copied from fam.h. Weird, I know */
99 typedef struct FAMEvent
{
103 gchar filename
[PATH_MAX
];
109 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn
,
110 MonoString
**filename
,
117 if (FAMNextEvent (conn
, &ev
) == 1) {
118 *filename
= mono_string_new_checked (mono_domain_get (), ev
.filename
, error
);
120 *reqnum
= ev
.fr
.reqnum
;
121 if (mono_error_set_pending_exception (error
))
133 interrupt_kevent (gpointer data
)
135 int *kq_ptr
= (int*)data
;
137 /* Interrupt the kevent () call by closing the fd */
139 /* Signal to managed code that the fd is closed */
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
)
152 gboolean interrupted
;
154 mono_thread_info_install_interrupt (interrupt_kevent
, kq_ptr
, &interrupted
);
162 res
= kevent (*kq_ptr
, (const struct kevent
*)changelist
, nchanges
, (struct kevent
*)eventlist
, nevents
, NULL
);
165 mono_thread_info_uninstall_interrupt (&interrupted
);
173 ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr
, gpointer changelist
, int nchanges
, gpointer eventlist
, int nevents
)
175 g_assert_not_reached ();
179 #endif /* #if HAVE_KQUEUE */