#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/io-private.h>
-#include <mono/io-layer/timefuncs-private.h>
-#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/io-portability.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-once.h>
#include <mono/utils/mono-logger-internals.h>
-#include <mono/utils/w32handle.h>
+#include <mono/metadata/w32handle.h>
/*
* If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
* 4MB array.
*/
static GHashTable *file_share_hash;
-static mono_mutex_t file_share_hash_mutex;
+static mono_mutex_t file_share_mutex;
-#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
-#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
+static void
+time_t_to_filetime (time_t timeval, WapiFileTime *filetime)
+{
+ guint64 ticks;
+
+ ticks = ((guint64)timeval * 10000000) + 116444736000000000ULL;
+ filetime->dwLowDateTime = ticks & 0xFFFFFFFF;
+ filetime->dwHighDateTime = ticks >> 32;
+}
static void
_wapi_handle_share_release (_WapiFileShare *share_info)
{
- int thr_ret;
+ /* Prevent new entries racing with us */
+ mono_os_mutex_lock (&file_share_mutex);
g_assert (share_info->handle_refs > 0);
-
- /* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert(thr_ret == 0);
+ share_info->handle_refs -= 1;
- if (InterlockedDecrement ((gint32 *)&share_info->handle_refs) == 0) {
- file_share_hash_lock ();
+ if (share_info->handle_refs == 0)
g_hash_table_remove (file_share_hash, share_info);
- file_share_hash_unlock ();
- }
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert (thr_ret == 0);
+ mono_os_mutex_unlock (&file_share_mutex);
}
static gint
guint32 *old_sharemode, guint32 *old_access, struct _WapiFileShare **share_info)
{
struct _WapiFileShare *file_share;
- int thr_ret;
gboolean exists = FALSE;
/* Prevent new entries racing with us */
- thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert (thr_ret == 0);
+ mono_os_mutex_lock (&file_share_mutex);
_WapiFileShare tmp;
* info. This is needed even if SHM is disabled, to track sharing inside
* the current process.
*/
- if (!file_share_hash) {
+ if (!file_share_hash)
file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
- mono_os_mutex_init_recursive (&file_share_hash_mutex);
- }
tmp.device = device;
tmp.inode = inode;
- file_share_hash_lock ();
-
file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
if (file_share) {
*old_sharemode = file_share->sharemode;
*old_access = file_share->access;
*share_info = file_share;
- InterlockedIncrement ((gint32 *)&file_share->handle_refs);
+ g_assert (file_share->handle_refs > 0);
+ file_share->handle_refs += 1;
+
exists = TRUE;
} else {
file_share = g_new0 (_WapiFileShare, 1);
file_share->device = device;
file_share->inode = inode;
- file_share->opened_by_pid = _wapi_getpid ();
+ file_share->opened_by_pid = wapi_getpid ();
file_share->sharemode = new_sharemode;
file_share->access = new_access;
file_share->handle_refs = 1;
g_hash_table_insert (file_share_hash, file_share, file_share);
}
- file_share_hash_unlock ();
-
- thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
- g_assert (thr_ret == 0);
+ mono_os_mutex_unlock (&file_share_mutex);
return(exists);
}
struct _WapiHandle_file *file_handle;
gboolean ok;
int fd, ret;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
do {
ret = read (fd, buffer, numbytes);
} while (ret == -1 && errno == EINTR &&
- !_wapi_thread_cur_apc_pending());
+ !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
gint err = errno;
gboolean ok;
int ret, fd;
off_t current_pos = 0;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
do {
ret = write (fd, buffer, numbytes);
} while (ret == -1 && errno == EINTR &&
- !_wapi_thread_cur_apc_pending());
+ !mono_thread_info_is_interrupt_state (info));
if (lock_while_writing) {
_wapi_unlock_file_region (fd, current_pos, numbytes);
struct stat statbuf;
off_t pos;
int ret, fd;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FILE,
(gpointer *)&file_handle);
do {
ret = write (fd, "", 1);
} while (ret == -1 && errno == EINTR &&
- !_wapi_thread_cur_apc_pending());
+ !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p extend write failed: %s", __func__, handle, strerror(errno));
do {
ret=ftruncate(fd, pos);
}
- while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p ftruncate failed: %s", __func__,
handle, strerror(errno));
struct _WapiHandle_file *console_handle;
gboolean ok;
int ret, fd;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
do {
ret=read(fd, buffer, numbytes);
- } while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ } while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if(ret==-1) {
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: read of handle %p error: %s", __func__, handle,
struct _WapiHandle_file *console_handle;
gboolean ok;
int ret, fd;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_CONSOLE,
(gpointer *)&console_handle);
do {
ret = write(fd, buffer, numbytes);
} while (ret == -1 && errno == EINTR &&
- !_wapi_thread_cur_apc_pending());
+ !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
if (errno == EINTR) {
struct _WapiHandle_file *pipe_handle;
gboolean ok;
int ret, fd;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
do {
ret=read(fd, buffer, numbytes);
- } while (ret==-1 && errno==EINTR && !_wapi_thread_cur_apc_pending());
+ } while (ret==-1 && errno==EINTR && !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
if (errno == EINTR) {
struct _WapiHandle_file *pipe_handle;
gboolean ok;
int ret, fd;
+ MonoThreadInfo *info = mono_thread_info_current ();
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_PIPE,
(gpointer *)&pipe_handle);
do {
ret = write (fd, buffer, numbytes);
} while (ret == -1 && errno == EINTR &&
- !_wapi_thread_cur_apc_pending());
+ !mono_thread_info_is_interrupt_state (info));
if (ret == -1) {
if (errno == EINTR) {
if (attrs & FILE_FLAG_RANDOM_ACCESS)
posix_fadvise (fd, 0, 0, POSIX_FADV_RANDOM);
#endif
-
+
+#ifdef F_RDAHEAD
+ if (attrs & FILE_FLAG_SEQUENTIAL_SCAN)
+ fcntl(fd, F_RDAHEAD, 1);
+#endif
+
#ifndef S_ISFIFO
#define S_ISFIFO(m) ((m & S_IFIFO) != 0)
#endif
case EXDEV:
/* Ignore here, it is dealt with below */
break;
-
+
+ case ENOENT:
+ /* We already know src exists. Must be dest that doesn't exist. */
+ _wapi_set_last_path_error_from_errno (NULL, utf8_dest_name);
+ break;
+
default:
- _wapi_set_last_path_error_from_errno (NULL, utf8_name);
+ _wapi_set_last_error_from_errno ();
}
}
int remain, n;
char *buf, *wbuf;
int buf_size = st_src->st_blksize;
+ MonoThreadInfo *info = mono_thread_info_current ();
buf_size = buf_size < 8192 ? 8192 : (buf_size > 65536 ? 65536 : buf_size);
- buf = (char *) malloc (buf_size);
+ buf = (char *) g_malloc (buf_size);
for (;;) {
remain = read (src_fd, buf, buf_size);
if (remain < 0) {
- if (errno == EINTR && !_wapi_thread_cur_apc_pending ())
+ if (errno == EINTR && !mono_thread_info_is_interrupt_state (info))
continue;
if (report_errors)
_wapi_set_last_error_from_errno ();
- free (buf);
+ g_free (buf);
return FALSE;
}
if (remain == 0) {
wbuf = buf;
while (remain > 0) {
if ((n = write (dest_fd, wbuf, remain)) < 0) {
- if (errno == EINTR && !_wapi_thread_cur_apc_pending ())
+ if (errno == EINTR && !mono_thread_info_is_interrupt_state (info))
continue;
if (report_errors)
_wapi_set_last_error_from_errno ();
MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: write failed.", __func__);
- free (buf);
+ g_free (buf);
return FALSE;
}
}
}
- free (buf);
+ g_free (buf);
return TRUE ;
}
gunichar2 *utf16_basename;
time_t create_time;
glong bytes;
- int thr_ret;
gboolean ret = FALSE;
ok=mono_w32handle_lookup (handle, MONO_W32HANDLE_FIND,
return(FALSE);
}
- thr_ret = mono_w32handle_lock_handle (handle);
- g_assert (thr_ret == 0);
+ mono_w32handle_lock_handle (handle);
retry:
if (find_handle->count >= find_handle->num) {
find_data->dwFileAttributes = _wapi_stat_to_file_attributes (utf8_filename, &buf, &linkbuf);
#endif
- _wapi_time_t_to_filetime (create_time, &find_data->ftCreationTime);
- _wapi_time_t_to_filetime (buf.st_atime, &find_data->ftLastAccessTime);
- _wapi_time_t_to_filetime (buf.st_mtime, &find_data->ftLastWriteTime);
+ time_t_to_filetime (create_time, &find_data->ftCreationTime);
+ time_t_to_filetime (buf.st_atime, &find_data->ftLastAccessTime);
+ time_t_to_filetime (buf.st_mtime, &find_data->ftLastWriteTime);
if (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
find_data->nFileSizeHigh = 0;
g_free (utf16_basename);
cleanup:
- thr_ret = mono_w32handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ mono_w32handle_unlock_handle (handle);
return(ret);
}
{
struct _WapiHandle_find *find_handle;
gboolean ok;
- int thr_ret;
if (handle == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- thr_ret = mono_w32handle_lock_handle (handle);
- g_assert (thr_ret == 0);
+ mono_w32handle_lock_handle (handle);
g_strfreev (find_handle->namelist);
g_free (find_handle->dir_part);
- thr_ret = mono_w32handle_unlock_handle (handle);
- g_assert (thr_ret == 0);
+ mono_w32handle_unlock_handle (handle);
mono_w32handle_unref (handle);
g_free (utf8_name);
- _wapi_time_t_to_filetime (create_time, &data->ftCreationTime);
- _wapi_time_t_to_filetime (buf.st_atime, &data->ftLastAccessTime);
- _wapi_time_t_to_filetime (buf.st_mtime, &data->ftLastWriteTime);
+ time_t_to_filetime (create_time, &data->ftCreationTime);
+ time_t_to_filetime (buf.st_atime, &data->ftLastAccessTime);
+ time_t_to_filetime (buf.st_mtime, &data->ftLastWriteTime);
if (data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
data->nFileSizeHigh = 0;
#endif
#if defined(HAVE_STATVFS) || defined(HAVE_STATFS)
-gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, WapiULargeInteger *free_bytes_avail,
- WapiULargeInteger *total_number_of_bytes,
- WapiULargeInteger *total_number_of_free_bytes)
+gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, ULARGE_INTEGER *free_bytes_avail,
+ ULARGE_INTEGER *total_number_of_bytes,
+ ULARGE_INTEGER *total_number_of_free_bytes)
{
#ifdef HAVE_STATVFS
struct statvfs fsstat;
return(TRUE);
}
#else
-gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, WapiULargeInteger *free_bytes_avail,
- WapiULargeInteger *total_number_of_bytes,
- WapiULargeInteger *total_number_of_free_bytes)
+gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, ULARGE_INTEGER *free_bytes_avail,
+ ULARGE_INTEGER *total_number_of_bytes,
+ ULARGE_INTEGER *total_number_of_free_bytes)
{
if (free_bytes_avail != NULL) {
free_bytes_avail->QuadPart = (guint64) -1;
_wapi_io_init (void)
{
mono_os_mutex_init (&stdhandle_mutex);
+ mono_os_mutex_init (&file_share_mutex);
mono_w32handle_register_ops (MONO_W32HANDLE_FILE, &_wapi_file_ops);
mono_w32handle_register_ops (MONO_W32HANDLE_CONSOLE, &_wapi_console_ops);
void
_wapi_io_cleanup (void)
{
- if (file_share_hash) {
+ mono_os_mutex_destroy (&file_share_mutex);
+
+ if (file_share_hash)
g_hash_table_destroy (file_share_hash);
- mono_os_mutex_destroy (&file_share_hash_mutex);
- }
}