aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/drivers/win32/win_efile.c
AgeCommit message (Collapse)Author
2013-01-17Use share flags for all file operations on WindowsFilipe David Borba Manana
Some file operations provided by the Erlang file module didn't open the target file with all the file share flags. This made some concurrent file operations against the same file fail on Windows, while on other platforms such as GNU/Linux or Mac OS X they succeed. The operations will fail only if they're performed concurrently by different threads (async IO threads or scheduler threads). For example, one Erlang process does a file:delete/1 call while another Erlang process is doing a filelib:file_size/1 call. This made the former process get an eacces error from the file:delete/1 call. On GNU/Linux or Mac OS X the call would succeed. Another example is if one Erlang process attempts to open a file for reading while another one is in the middle of a file:read_file_info/1 call (after it opened the file and before it closed the file). It's easy to verify that if a file is not open with all the share flags, it's impossible for other threads (even if they belong to the same OS process) to open the file while the file is not closed by the first thread. The following test program shows this: #include <windows.h> #include <iostream> // Must be an existing file //#define SHARE_FLAGS (FILE_SHARE_READ) static DWORD WINAPI MyThreadFunction(LPVOID lpParam); static char *lastError(); int main(int argc, char *argv[]) { DWORD threadId; HANDLE threadHandle, hFile; hFile = CreateFile(FILENAME, GENERIC_READ, SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "File open error from main: " << lastError() << std::endl; return 1; } std::cout << "Main thread opened file successfully" << std::endl; threadHandle = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, &threadId); if (threadHandle == INVALID_HANDLE_VALUE) { std::cerr << "Thread create error from main: " << lastError() << std::endl; return 1; } WaitForSingleObject(threadHandle, INFINITE); CloseHandle(threadHandle); CloseHandle(hFile); return 0; } static DWORD WINAPI MyThreadFunction( LPVOID lpParam ) { HANDLE hFile; hFile = CreateFile(FILENAME, GENERIC_READ, SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "File open error from second thread: " << lastError() << std::endl; return 1; } std::cout << "Second thread opened file successfully" << std::endl; CloseHandle(hFile); return 0; } static char *lastError() { static char *buf = NULL; DWORD dw = GetLastError(); if (buf != NULL) { LocalFree((LPTSTR) &buf); } FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); return buf; } Rnning this program with SHARE_FLAGS set to 0 (as efile_fileinfo() does for e.g.), shows that the second thread is unable to open the file: C:\cygwin\home\fdmanana\tmp>touch foo.bar C:\cygwin\home\fdmanana\tmp>threads_fopen_test.exe Main thread opened file successfully File open error from second thread: The process cannot access the file because it is being used by another process. Changing the program's SHARE_FLAGS to FILE_SHARE_READ, shows that both threads are able to open the file: C:\cygwin\home\fdmanana\tmp>touch foo.bar C:\cygwin\home\fdmanana\tmp>threads_test.exe Main thread opened file successfully Second thread opened file successfully Same logic applies to opening files for writing or deleting and renaming files while they're open by some other thread that didn't specify the flags FILE_SHARE_WRITE and FILE_SHARE_DELETE.
2013-01-09Add file:allocate/3 operationFilipe David Manana
This operation allows pre-allocation of space for files. It succeeds only on systems that support such operation. The POSIX standard defines the optional system call posix_fallocate() to implement this feature. However, some systems implement more specific functions to accomplish the same operation. On Linux, if the more specific function fallocate() is implemented, it is used instead of posix_fallocate(), falling back to posix_fallocate() if the fallocate() call failed (it's only supported for the ext4, ocfs2, xfs and btrfs file systems at the moment). On Mac OS X it uses the specific fcntl() operation F_PREALLOCATE, falling back to posix_fallocate() if it's available (at the moment Mac OS X doesn't provide posix_fallocate()). On any other UNIX system, it uses posix_fallocate() if it's available. Any other system not providing this system call or any function to pre-allocate space for files, this operation always fails with the ENOTSUP POSIX error.
2012-08-31Update copyright yearsBjörn-Egil Dahlberg
2012-08-30Teach VM not to dump core on long pathnamesPatrik Nyblom
Long input paths (longer than MAX_PATH) would get copied into a buffer of size MAX_PATH for read_link and altname in efile_drv. Also fixed misuse of size_t parameter as wchar_t * string length in win_efile:efile_readlink.
2011-12-20erts: rewrite efile_writev to handle partial writes correctlyRaimo Niskanen
2011-12-08Teach windows sys_localtime_rBjörn-Egil Dahlberg
2011-12-02Fix undefined ctime for invalid file handlesBjörn-Egil Dahlberg
* ctime were never defined for invalid file handles * fix epoch <-> fileinfo conversions
2011-12-02Fix EPOCH <-> FILETIME conversionBjörn-Egil Dahlberg
2011-12-02Teach win32 efile driver epochsBjörn-Egil Dahlberg
Conflicts: erts/emulator/drivers/win32/win_efile.c
2011-12-02Build Win64 Erlang emulator using MSYSunknown
Still does not run, just compiles.
2011-11-10Remove exec bit from files related to: XML, make, CRicardo Catalinas Jiménez
2011-05-10Add error code for cyclic symbolic links and make directory links readablePatrik Nyblom
2011-03-11Update copyright yearsBjörn-Egil Dahlberg
2011-02-09Fix win32 file drivers atime/mtimeBjörn-Egil Dahlberg
When setting file_info it will now correctly set access and modified time. Previously these entities were swapped.
2010-11-30Teach filelib to use re in unicode mode when filenames are not rawPatrik Nyblom
2010-11-30Adapt new soft and hard link routines on Windos to UnicodePatrik Nyblom
Also close find-handles in altname and other minor corrections to patch
2010-11-30Make Unicode filenames work on WindowsPatrik Nyblom
2010-11-29Merge branch 'jr/windows-file-append' into devPatrik Nyblom
* jr/windows-file-append: Fix appending to large files (>4GB) on Windows OTP-8958
2010-10-14Add Win32 support for hard and symbolic file system linksBlaine Whittle
Hard linking requires XP or later and a NTFS formatted drive. Symbolic linking requires Windows Vista, Windows Server 2008, Windows 7 or later. Symbolic linking on earlier versions of Windows will return {error, enotsup}. file:make_link/2, file:make_sym_link/2 and file:read_link/1 are all implemented. file:read_file_info/1 does NOT return the number of hard links on the file as this results in performance problems for read_file_info/1, however this can be enabled by uncommenting a few lines of code. The original path was submitted on 9/2/2009 by Alex Tearse-Doyle.
2010-09-30Fix appending to large files (>4GB) on WindowsJuhani Rankimies
Append mode doesn't work for files larger that 4GB on Windows. Caused by incorrect usage of SetFilePointer in win_efile.c. Fix uses OVERLAPPED structure to specify write position (EOF). http://msdn.microsoft.com/en-us/library/aa365747.aspx Opening file in append mode was also considered, but rejected, because it might cause backwards incompatibility by limiting applicable operations on the descriptor. SetFilePointerEx was not used because it would caused more system calls than using OVERLAPPED structure.
2010-06-04Support opening files in exclusive modeMichael Santos
Add an option that atomically tests for the existence of a file and creates it if the file does not exist, by passing the O_EXCL flag to open() on Unix and CREATE_NEW flag on Windows. Support for O_EXCL varies across platforms and filesystems. {ok, Fd} = file:open("/tmp/foo", [write,exclusive]), {error, eexist} = file:open("/tmp/foo", [write,exclusive]).
2010-06-02Windows: Open files with FILE_SHARE_DELETE to get closer to UNIX semanticsJan Lehnardt
See dwShareMode on http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx
2010-05-24Merge branch 'fm/file-operations' into devErlang/OTP
* fm/file-operations: Update preloaded modules Add file:advise/4 - a wrapper to the POSIX syscall posix_fadvise Add file:datasync/1 for syncing file contents only sys.h: Correct the get_int64() macro OTP-8637 fm/file-operations The functions file:advise/4 and file:datasync/1 have been added. (Thanks to Filipe David Manana.)
2010-05-20Add file:advise/4 - a wrapper to the POSIX syscall posix_fadviseFilipe David Manana
Useful for informing the Operating System about the access pattern for a file's data, so that it can adapt the caching strategy to maximize disk IO performance.
2010-05-20Add file:datasync/1 for syncing file contents onlyFilipe David Manana
file:datasync/1 invokes the POSIX system call "int fdatasync(int fd)". This system call is similar to "fsync" but, unlike fsync, it does not update the metadata associated with the file (like the access time for example). It's used by many DBMSs (MySQL and SQLite of example) to increase disk IO performance, as it avoids disk seeks and disk write operations compared to fsync. More details on it at: http://linux.die.net/man/2/fdatasync An example, from the MySQL source: http://bazaar.launchpad.net/~mysql/mysql-server/mysql-5.1-telco-6.1/annotate/head%3A/mysys/my_sync.c#L61 This new function just calls fsync on systems not implementing fdatasync.
2009-11-20The R13B03 release.OTP_R13B03Erlang/OTP