Skip to content

CoreFoundation Windows Port #1783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
2 changes: 1 addition & 1 deletion CoreFoundation/Base.subproj/CFFileUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
}

Boolean isDirectory = file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Boolean result = fileHandler(fileName, isDirectory ? DT_DIR : DT_REG);
Boolean result = fileHandler(fileName, NULL, isDirectory ? DT_DIR : DT_REG);
CFRelease(fileName);
if (!result) break;
} while (FindNextFileW(handle, &file));
Expand Down
54 changes: 25 additions & 29 deletions CoreFoundation/Base.subproj/CFInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,6 @@ typedef struct os_log_s *os_log_t;
#ifndef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}}
#endif
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}}
#endif
#endif

#if defined(__BIG_ENDIAN__)
Expand Down Expand Up @@ -522,53 +519,46 @@ typedef pthread_mutex_t CFLock_t;

#define __CFLockTry(LP) ({ pthread_mutex_trylock(LP) == 0; })

#elif DEPLOYMENT_TARGET_WINDOWS
#elif _POSIX_THREADS

typedef int32_t CFLock_t;
#define CFLockInit 0
typedef pthread_mutex_t CFLock_t;
#if DEPLOYMENT_TARGET_FREEBSD
#define CFLockInit ((pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER)
#else
#define CFLockInit ((pthread_mutex_t)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
#endif
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)

CF_INLINE void __CFLock(volatile CFLock_t *lock) {
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
Sleep(0);
}
}

CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
MemoryBarrier();
*lock = 0;
}
#define __CFLock(LP) ({ (void)pthread_mutex_lock(LP); })
#define __CFUnlock(LP) ({ (void)pthread_mutex_unlock(LP); })
#define __CFLockTry(LP) ({ pthread_mutex_trylock(LP) == 0; })

CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
}
typedef int32_t OSSpinLock;
#define OS_SPINLOCK_INIT 0
#define OSSpinLockLock(lock) ({ while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) sleep(0); })
#define OSSpinLockUnlock(lock) ({ __sync_synchronize(); *lock = 0; })

#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CFLock is not really supposed to be a full pthread_mutex, instead it should be a super-lightweight lock ala futex or os_unfair_lock etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay. What about the other pthread_mutex_t instances? This is a problem since there is no pthread_t on Windows, so trying to figure out how to define this properly is interesting. The other thing that complicates this is that the types for recursive mutexes and mutexes are different, so you cannot just use pthread_mutex_t as a typedef.

#elif DEPLOYMENT_TARGET_WINDOWS

typedef int32_t CFLock_t;
#define CFLockInit 0
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)

CF_INLINE void __CFLock(volatile CFLock_t *lock) {
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
sleep(0);
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
Sleep(0);
}
}

CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
__sync_synchronize();
MemoryBarrier();
*lock = 0;
}

CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
}

typedef CFLock_t OSSpinLock;
#define OS_SPINLOCK_INIT CFLockInit
#define OSSpinLockLock(lock) __CFLock(lock)
#define OSSpinLockUnlock(lock) __CFUnlock(lock)

#else

#warning CF locks not defined for this platform -- CF is not thread-safe
Expand All @@ -579,6 +569,12 @@ typedef CFLock_t OSSpinLock;

#if __has_include(<os/lock.h>)
#include <os/lock.h>
#elif DEPLOYMENT_TARGET_WINDOWS
#define OS_UNFAIR_LOCK_INIT SRWLOCK_INIT
typedef SRWLOCK os_unfair_lock;
typedef SRWLOCK *os_unfair_lock_t;
static void os_unfair_lock_lock(os_unfair_lock_t lock) { AcquireSRWLockExclusive(lock); }
static void os_unfair_lock_unlock(os_unfair_lock_t lock) { ReleaseSRWLockExclusive(lock); }
#elif _POSIX_THREADS
#define OS_UNFAIR_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t os_unfair_lock;
Expand Down
7 changes: 6 additions & 1 deletion CoreFoundation/Base.subproj/CFPlatform.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,14 +677,19 @@ static void __CFTSDFinalize(void *arg) {
table->destructors[i]((void *)(old));
}
}


#if _POSIX_THREADS
if (table->destructorCount == PTHREAD_DESTRUCTOR_ITERATIONS - 1) { // On PTHREAD_DESTRUCTOR_ITERATIONS-1 call, destroy our data
free(table);

// Now if the destructor is called again we will take the shortcut at the beginning of this function.
__CFTSDSetSpecific(CF_TSD_BAD_PTR);
return;
}
#else
free(table);
__CFTSDSetSpecific(CF_TSD_BAD_PTR);
#endif
}

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
Expand Down
6 changes: 3 additions & 3 deletions CoreFoundation/Locale.subproj/CFDateFormatter.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRef allocato

static Boolean useTemplatePatternGenerator(CFLocaleRef locale, void(^work)(UDateTimePatternGenerator *ptg)) {
static UDateTimePatternGenerator *ptg;
static pthread_mutex_t ptgLock = PTHREAD_MUTEX_INITIALIZER;
static CFLock_t ptgLock = CFLockInit;
static const char *ptgLocaleName;
CFStringRef ln = locale ? CFLocaleGetIdentifier(locale) : CFSTR("");
char buffer[BUFFER_SIZE];
Expand All @@ -73,7 +73,7 @@ static Boolean useTemplatePatternGenerator(CFLocaleRef locale, void(^work)(UDate
free((void *)ptgLocaleName);
ptgLocaleName = NULL;
};
pthread_mutex_lock(&ptgLock);
__CFLock(&ptgLock);
if (ptgLocaleName && strcmp(ptgLocaleName, localeName) != 0) {
flushCache();
}
Expand All @@ -88,7 +88,7 @@ static Boolean useTemplatePatternGenerator(CFLocaleRef locale, void(^work)(UDate
if (result && work) {
work(ptg);
}
pthread_mutex_unlock(&ptgLock);
__CFUnlock(&ptgLock);
return result;
}

Expand Down
Loading