1
0
Fork 0

issue #662: ArangoDB on Windows hanging

This commit is contained in:
Jan Steemann 2013-11-19 16:27:26 +01:00
parent 87aed55acf
commit af6da9a652
7 changed files with 87 additions and 370 deletions

View File

@ -67,6 +67,28 @@ v1.5.x (XXXX-XX-XX)
v1.4.2 (XXXX-XX-XX)
-------------------
* ported Windows version to use native Windows API SRWLocks (slim read-write locks)
and condition variables instead of homemade versions
MSDN states the following about the compatibility of SRWLocks and Condition Variables:
Minimum supported client:
Windows Server 2008 [desktop apps | Windows Store apps]
Minimum supported server:
Windows Vista [desktop apps | Windows Store apps]
* fixed issue #662: ArangoDB on Windows hanging
This fixes a deadlock issue that occurred on Windows when documents were written to
a collection at the same time when some other thread tried to drop the collection.
* fixed file-based logging in Windows
the logger complained on startup if the specified log file already existed
* fixed startup of server in daemon mode (`--daemon` startup option)
* fixed a segfault in the AQL optimiser
* issue #671: Method graph.measurement does not exist

View File

@ -213,8 +213,12 @@ static bool UnregisterCollection (TRI_vocbase_t* vocbase,
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, collection->_name);
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsById, &collection->_cid);
// only if we find the collection by its id, we can delete it by name
if (TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsById, &collection->_cid) != NULL) {
// this is because someone else might have created a new collection with the same name,
// but with a different id
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, collection->_name);
}
TRI_ASSERT_MAINTAINER(vocbase->_collectionsByName._nrUsed == vocbase->_collectionsById._nrUsed);
@ -237,9 +241,9 @@ static bool UnloadCollectionCallback (TRI_collection_t* col, void* data) {
TRI_document_collection_t* document;
int res;
collection = data;
collection = (TRI_vocbase_col_t*) data;
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_UNLOADING) {
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
@ -328,7 +332,7 @@ static bool DropCollectionCallback (TRI_collection_t* col,
}
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
if (collection->_status != TRI_VOC_COL_STATUS_DELETED) {
LOG_ERROR("someone resurrected the collection '%s'", collection->_name);
@ -559,7 +563,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
// check name
res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsByName, name, collection, &found);
if (found != NULL) {
LOG_ERROR("duplicate entry for collection name '%s'", name);
LOG_ERROR("collection id %llu has same name as already added collection %llu",
@ -582,8 +586,9 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
}
// check collection identifier
assert(collection->_cid == cid);
res = TRI_InsertKeyAssociativePointer2(&vocbase->_collectionsById, &cid, collection, &found);
if (found != NULL) {
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, name);
@ -601,7 +606,6 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsById, &cid);
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, name);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, collection);
TRI_set_errno(res);
return NULL;
@ -720,8 +724,7 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
void const* found;
int res;
// lock collection because we are going to change the name
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// this must be done after the collection lock
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
@ -815,7 +818,7 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, oldName);
TRI_CopyString(collection->_name, newName, sizeof(collection->_name) - 1);
// this shouldn't fail, as we removed an element above so adding one should be ok
found = TRI_InsertKeyAssociativePointer(&vocbase->_collectionsByName, newName, CONST_CAST(collection), false);
assert(found == NULL);
@ -1090,7 +1093,7 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase,
// write lock
// .............................................................................
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// someone else loaded the collection, release the WRITE lock and try again
if (collection->_status == TRI_VOC_COL_STATUS_LOADED) {
@ -1980,7 +1983,7 @@ int TRI_UnloadCollectionVocBase (TRI_vocbase_t* vocbase,
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// cannot unload a corrupted collection
if (collection->_status == TRI_VOC_COL_STATUS_CORRUPTED) {
@ -2065,14 +2068,14 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase,
TRI_ReadLockReadWriteLock(&vocbase->_inventoryLock);
// mark collection as deleted
TRI_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(collection);
// .............................................................................
// collection already deleted
// .............................................................................
if (collection->_status == TRI_VOC_COL_STATUS_DELETED) {
// mark collection as deleted
UnregisterCollection(vocbase, collection, generatingServer);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
@ -2101,7 +2104,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase,
// remove dangling .json.tmp file if it exists
tmpFile = TRI_Concatenate4String(collection->_path, TRI_DIR_SEPARATOR_STR, TRI_VOC_PARAMETER_FILE, ".tmp");
if (tmpFile != NULL) {
if (TRI_ExistsFile(tmpFile)) {
TRI_UnlinkFile(tmpFile);
@ -2125,7 +2128,6 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase,
}
collection->_status = TRI_VOC_COL_STATUS_DELETED;
UnregisterCollection(vocbase, collection, generatingServer);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
@ -2180,6 +2182,7 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase,
}
collection->_status = TRI_VOC_COL_STATUS_DELETED;
UnregisterCollection(vocbase, collection, generatingServer);
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);

View File

@ -114,6 +114,13 @@ struct TRI_vocbase_defaults_s;
#define TRI_READ_UNLOCK_STATUS_VOCBASE_COL(a) \
TRI_ReadUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to write lock the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
#define TRI_TRY_WRITE_LOCK_STATUS_VOCBASE_COL(a) \
TRI_TryWriteLockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the vocbase collection status
////////////////////////////////////////////////////////////////////////////////
@ -128,6 +135,15 @@ struct TRI_vocbase_defaults_s;
#define TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(a) \
TRI_WriteUnlockReadWriteLock(&(a)->_lock)
////////////////////////////////////////////////////////////////////////////////
/// @brief write locks the vocbase collection status using spinning
////////////////////////////////////////////////////////////////////////////////
#define TRI_EVENTUAL_WRITE_LOCK_STATUS_VOCBASE_COL(a) \
while (! TRI_TRY_WRITE_LOCK_STATUS_VOCBASE_COL(a)) { \
usleep(1000); \
}
////////////////////////////////////////////////////////////////////////////////
/// @brief locks the synchroniser waiters
////////////////////////////////////////////////////////////////////////////////

View File

@ -208,43 +208,7 @@ void TRI_UnlockSpin (TRI_spin_t* spin) {
////////////////////////////////////////////////////////////////////////////////
void TRI_InitReadWriteLock (TRI_read_write_lock_t* lock) {
// ...........................................................................
// set the number of readers reading on the read_write lock to 0
// ...........................................................................
lock->_readers = 0;
// ...........................................................................
// Signaled: writer has no access
// Non-Signaled: writer has access, block readers
// Creates an event which allows a thread to wait on it (perhaps should use
// a mutux rather than an event here). The writer event is set to signalled
// when CreateEvent is called with these parameters.
// ...........................................................................
lock->_writerEvent = CreateEvent(0, TRUE, TRUE, 0);
// ...........................................................................
// Signaled: no readers
// Non-Signaled: some readers have access, block writer
// Same as the writer event above except this is the reader event
// ...........................................................................
lock->_readersEvent = CreateEvent(0, TRUE, TRUE, 0);
// ...........................................................................
// Creates critical sections for writer and readers.
// Waits for ownership of the specified critical section object.
// The function returns when the calling thread is granted ownership.
// ...........................................................................
InitializeCriticalSection(&lock->_lockWriter);
InitializeCriticalSection(&lock->_lockReaders);
InitializeSRWLock(&lock->_lock);
}
////////////////////////////////////////////////////////////////////////////////
@ -252,11 +216,6 @@ void TRI_InitReadWriteLock (TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyReadWriteLock (TRI_read_write_lock_t* lock) {
DeleteCriticalSection(&lock->_lockWriter);
DeleteCriticalSection(&lock->_lockReaders);
CloseHandle(lock->_writerEvent);
CloseHandle(lock->_readersEvent);
}
////////////////////////////////////////////////////////////////////////////////
@ -272,56 +231,6 @@ void TRI_DestroyReadWriteLock (TRI_read_write_lock_t* lock) {
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief increments readers
////////////////////////////////////////////////////////////////////////////////
static void IncrementReaders (TRI_read_write_lock_t* lock) {
// ...........................................................................
// increment the number of readers we have on the read_write lock
// ...........................................................................
lock->_readers++;
// ...........................................................................
// Since the number of readers must be positive, set the readers event to
// non-signalled so that any write event will have to wait.
// ...........................................................................
ResetEvent(lock->_readersEvent);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief decrements readers
////////////////////////////////////////////////////////////////////////////////
static void DecrementReaders (TRI_read_write_lock_t* lock) {
// ...........................................................................
// reduce the number of readers using the read_write lock by 1
// ...........................................................................
lock->_readers--;
// ...........................................................................
// When the number of readers is 0, set the event to signalled which allows
// a writer to use the read_write lock.
// ...........................................................................
if (lock->_readers == 0) {
SetEvent(lock->_readersEvent);
}
else if (lock->_readers < 0) {
LOG_FATAL_AND_EXIT("reader count is negative");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
@ -336,20 +245,7 @@ static void DecrementReaders (TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
bool TRI_TryReadLockReadWriteLock (TRI_read_write_lock_t* lock) {
WaitForSingleObject(lock->_writerEvent, 10); // 10 millis timeout
EnterCriticalSection(&lock->_lockReaders);
IncrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
EnterCriticalSection(&lock->_lockReaders);
DecrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
return false;
}
return true;
return (TryAcquireSRWLockShared(&lock->_lock) != 0);
}
////////////////////////////////////////////////////////////////////////////////
@ -357,43 +253,7 @@ bool TRI_TryReadLockReadWriteLock (TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_ReadLockReadWriteLock (TRI_read_write_lock_t* lock) {
while (true) {
// ........................................................................
// Waits for a writer to finish if there is one. This function only
// returns when the writer event is in a signalled state
// ........................................................................
WaitForSingleObject(lock->_writerEvent, INFINITE);
// .........................................................................
// This thread will wait here until this resource becomes excusively available
// .........................................................................
EnterCriticalSection(&lock->_lockReaders);
IncrementReaders(lock);
// .........................................................................
// allows some other thread to use this resource
// .........................................................................
LeaveCriticalSection(&lock->_lockReaders);
// it could have happened that the writer event is no longer in a signalled
// state. Between leaving the crtical section and here a writer sneaked in.
//
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
EnterCriticalSection(&lock->_lockReaders);
DecrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
}
else {
break;
}
}
AcquireSRWLockShared(&lock->_lock);
}
////////////////////////////////////////////////////////////////////////////////
@ -401,98 +261,15 @@ void TRI_ReadLockReadWriteLock (TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_ReadUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
EnterCriticalSection(&lock->_lockReaders);
/* this is wrong since it is possible for the write locker to block this event
// a write lock eists
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
LOG_FATAL_AND_EXIT("write lock, but trying to unlock read");
}
// at least one reader exists
else if (0 < lock->_readers) {
DecrementReaders(lock);
}
// ups, no writer and no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
*/
if (0 < lock->_readers) {
DecrementReaders(lock);
}
// oops no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader, but trying to unlock read lock");
}
LeaveCriticalSection(&lock->_lockReaders);
ReleaseSRWLockShared(&lock->_lock);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to write lock a read-write lock
////////////////////////////////////////////////////////////////////////////////
bool TRI_TryWriteLockReadWriteLock (TRI_read_write_lock_t* lock) {
BOOL result;
// ...........................................................................
// Here we use TryEnterCriticalSection instead of EnterCriticalSection
// There could already be a write lock - which will actuall block from this
// point on.
// ...........................................................................
result = TryEnterCriticalSection(&lock->_lockWriter);
if (result == 0) {
// appears some other writer is writing
return false;
}
// ...........................................................................
// Wait until the lock->_writerEvent is in a 'signalled' state
// This might fail because a reader is just about to read
// ...........................................................................
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
LeaveCriticalSection(&lock->_lockWriter);
return false;
}
// ...........................................................................
// Set _writeEvent as nonsignalled -- this will block other read/write
// lockers
// ...........................................................................
ResetEvent(lock->_writerEvent);
// ...........................................................................
// If there are ANY read locks outstanding, leave
// ...........................................................................
if (WaitForSingleObject(lock->_readersEvent, 0) != WAIT_OBJECT_0) {
LeaveCriticalSection(&lock->_lockWriter);
SetEvent(lock->_writerEvent);
return false;
}
// ...........................................................................
// Allow other threads to access this function
// ...........................................................................
LeaveCriticalSection(&lock->_lockWriter);
return true;
return (TryAcquireSRWLockExclusive(&lock->_lock) != 0);
}
////////////////////////////////////////////////////////////////////////////////
@ -500,99 +277,15 @@ bool TRI_TryWriteLockReadWriteLock (TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_WriteLockReadWriteLock (TRI_read_write_lock_t* lock) {
// ...........................................................................
// Lock so no other thread can access this
// EnterCriticalSection(&lock->_lockWriter) will block this thread until
// it has been released by the other thread.
// ...........................................................................
EnterCriticalSection(&lock->_lockWriter);
// ...........................................................................
// Wait until the lock->_writerEvent is in a 'signalled' state
// ...........................................................................
WaitForSingleObject(lock->_writerEvent, INFINITE);
// ...........................................................................
// Set _writeEvent as nonsignalled -- this will block other read/write
// lockers
// ...........................................................................
ResetEvent(lock->_writerEvent);
// ...........................................................................
// If there are ANY read locks outstanding, then wait until these are cleared
// ...........................................................................
WaitForSingleObject(lock->_readersEvent, INFINITE);
// ...........................................................................
// Allow other threads to access this function
// ...........................................................................
LeaveCriticalSection(&lock->_lockWriter);
AcquireSRWLockExclusive(&lock->_lock);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief write unlocks read-write lock
////////////////////////////////////////////////////////////////////////////////
void TRI_WriteUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
// ...........................................................................
// Write lock this _lockReader so no other threads can access this
// This will block this thread until it is released by the other thread
// We do not need to lock the _lockWriter SINCE the TRI_WriteLockReadWriteLock
// function above will lock (due to the ResetEvent(lock->_writerEvent); )
// ...........................................................................
EnterCriticalSection(&lock->_lockReaders);
// ...........................................................................
// In the function TRI_WriteLockReadWriteLock we set the _writerEvent to
// 'nonsignalled'. So if a write lock exists clear it by setting it to
// 'signalled'
// ...........................................................................
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
SetEvent(lock->_writerEvent);
}
// ...........................................................................
// Oops at least one reader exists - something terrible happened.
// ...........................................................................
else if (0 < lock->_readers) {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("read lock, but trying to unlock write");
}
// ...........................................................................
// Oops we are trying to unlock a write lock, but there isn't one! Something
// terrible happend.
// ...........................................................................
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
// ...........................................................................
// Allow read locks to be applied now.
// ...........................................................................
LeaveCriticalSection(&lock->_lockReaders);
ReleaseSRWLockExclusive(&lock->_lock);
}
////////////////////////////////////////////////////////////////////////////////
@ -715,7 +408,6 @@ void TRI_UnlockCondition (TRI_condition_t* cond) {
LeaveCriticalSection(&cond->_lockWaiters);
}
// -----------------------------------------------------------------------------
// COMPARE & SWAP operations below for windows
// Note that for the MAC OS we use the 'barrier' functions which ensure that

View File

@ -65,13 +65,7 @@ TRI_mutex_t;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_read_write_lock_s {
HANDLE _writerEvent;
HANDLE _readersEvent;
int _readers;
CRITICAL_SECTION _lockWriter;
CRITICAL_SECTION _lockReaders;
SRWLOCK _lock;
}
TRI_read_write_lock_t;

View File

@ -57,16 +57,15 @@ _invalid_parameter_handler newInvalidHandleHandler;
/// @{
////////////////////////////////////////////////////////////////////////////////
int ftruncate(int fd, long newSize) {
int ftruncate (int fd, long newSize) {
int result = _chsize(fd, newSize);
return result;
}
int getpagesize(void) {
int getpagesize (void) {
static int pageSize = 0; // only define it once
if (!pageSize) {
if (! pageSize) {
// first time, so call the system info function
SYSTEM_INFO systemInfo;
GetSystemInfo (&systemInfo);
@ -76,22 +75,20 @@ int getpagesize(void) {
return pageSize;
}
////////////////////////////////////////////////////////////////////////////////
// Calls the windows Sleep function which always sleeps for milliseconds
////////////////////////////////////////////////////////////////////////////////
void TRI_sleep(unsigned long waitTime) {
void TRI_sleep (unsigned long waitTime) {
Sleep(waitTime * 1000);
}
////////////////////////////////////////////////////////////////////////////////
// Calls a timer which waits for a signal after the elapsed time.
// The timer is acurate to 100nanoseconds
// The timer is accurate to 100nanoseconds
////////////////////////////////////////////////////////////////////////////////
void TRI_usleep(unsigned long waitTime) {
void TRI_usleep (unsigned long waitTime) {
int result;
HANDLE hTimer = NULL; // stores the handle of the timer object
LARGE_INTEGER wTime; // essentially a 64bit number
@ -109,7 +106,7 @@ void TRI_usleep(unsigned long waitTime) {
abort();
}
// Set timer to wait for indicated micro seconds.
if (!SetWaitableTimer(hTimer, &wTime, 0, NULL, NULL, 0)) {
if (! SetWaitableTimer(hTimer, &wTime, 0, NULL, NULL, 0)) {
// not much we can do at this low level
CloseHandle(hTimer);
return;
@ -135,14 +132,13 @@ void TRI_usleep(unsigned long waitTime) {
// for now is to ignore error and hope it goes away!
////////////////////////////////////////////////////////////////////////////////
static void InvalidParameterHandler(const wchar_t* expression, // expression sent to function - NULL
const wchar_t* function, // name of function - NULL
const wchar_t* file, // file where code resides - NULL
unsigned int line, // line within file - NULL
uintptr_t pReserved) { // in case microsoft forget something
static void InvalidParameterHandler (const wchar_t* expression, // expression sent to function - NULL
const wchar_t* function, // name of function - NULL
const wchar_t* file, // file where code resides - NULL
unsigned int line, // line within file - NULL
uintptr_t pReserved) { // in case microsoft forget something
LOG_ERROR("Invalid handle parameter passed");
/* start oreste -debug */
/*
if (expression != 0) {
wprintf(L"win-utils.c:InvalidParameterHandler:EXPRESSION = %s\n",expression);
}
@ -161,14 +157,12 @@ static void InvalidParameterHandler(const wchar_t* expression, // expression sen
else {
wprintf(L"win-utils.c:InvalidParameterHandler:FILE = NULL\n");
}
printf("oreste:win-utils.c:InvalidParameterHandler:LINE = %ud\n",line);
/* end oreste -debug */
*/
//abort();
// TODO: use the wcstombs_s function to convert wchar to char - since all the above
// wchar never will contain 2 byte chars
}
////////////////////////////////////////////////////////////////////////////////
// Called from the 'main' and performs any initialisation requirements which
// are specific to windows.
@ -178,8 +172,8 @@ static void InvalidParameterHandler(const wchar_t* expression, // expression sen
// calling function should decide what to do.
////////////////////////////////////////////////////////////////////////////////
int finaliseWindows(const TRI_win_finalise_e finaliseWhat, const char* data) {
int finaliseWindows (const TRI_win_finalise_e finaliseWhat,
const char* data) {
int result = 0;
// ............................................................................
@ -209,10 +203,8 @@ int finaliseWindows(const TRI_win_finalise_e finaliseWhat, const char* data) {
return -1;
}
int initialiseWindows(const TRI_win_initialise_e initialiseWhat, const char* data) {
int initialiseWindows (const TRI_win_initialise_e initialiseWhat,
const char* data) {
// ............................................................................
// The data is used to transport information from the calling function to here
@ -273,7 +265,6 @@ int initialiseWindows(const TRI_win_initialise_e initialiseWhat, const char* dat
}
int TRI_createFile (const char* filename, int openFlags, int modeFlags) {
HANDLE fileHandle;
int fileDescriptor;
@ -282,11 +273,10 @@ int TRI_createFile (const char* filename, int openFlags, int modeFlags) {
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_NEW,
(openFlags & O_APPEND) ? OPEN_ALWAYS : CREATE_NEW,
0,
NULL);
if (fileHandle == INVALID_HANDLE_VALUE) {
return -1;
}

View File

@ -106,14 +106,14 @@ int TRI_openFile (const char* filename, int openFlags);
// this provides a translation
// .............................................................................
void TRI_sleep(unsigned long);
void TRI_sleep (unsigned long);
// .............................................................................
// there is no usleep (micro sleep) in windows, so we create one here
// .............................................................................
void TRI_usleep(unsigned long);
void TRI_usleep (unsigned long);
////////////////////////////////////////////////////////////////////////////////
/// @}