Skip to content
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

Use tinycthread on all platforms #79

Merged
merged 2 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@
*.so
*.dll
inst/doc
src/Makevars
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: later
Type: Package
Title: Utilities for Delaying Function Execution
Version: 0.7.5.9000
Version: 0.7.5.9001
Authors@R: c(
person("Joe", "Cheng", role = c("aut", "cre"), email = "[email protected]"),
person(family = "RStudio", role = "cph"),
Expand Down
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## later 0.7.5.9000
## later 0.7.5.9001

* Fixed [issue #77](https://github.com/r-lib/later/issues/77): On some platforms, the system's C library has support for C11-style threads, but there is no `threads.h` header file. In this case, later's configure script tried to use the tinycthread, but upon linking, there were function name conflicts between tinycthread and the system's C library. Later no longer tries to use the system's `threads.h`, and the functions in tinycthread were renamed so that they do not accidentally link to the system C library's C11-style thread functions. [PR #79](https://github.com/r-lib/later/pull/79)

* Added `all` argument to `run_now()`; defaults to `TRUE`, but if set to `FALSE`, then `run_now` will run at most one later operation before returning. [PR #75](https://github.com/r-lib/later/pull/75)

Expand Down
3 changes: 0 additions & 3 deletions cleanup

This file was deleted.

45 changes: 0 additions & 45 deletions configure

This file was deleted.

6 changes: 2 additions & 4 deletions src/Makevars.in → src/Makevars
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
PKG_CPPFLAGS = -pthread @cppflags@
PKG_LIBS = -pthread @libs@
PKG_CPPFLAGS = -pthread
PKG_LIBS = -pthread

# Uncomment to enable thread assertions
# PKG_CPPFLAGS += -DDEBUG_THREAD -UNDEBUG

$(SHLIB): @libs@
7 changes: 0 additions & 7 deletions src/Makevars.win

This file was deleted.

58 changes: 58 additions & 0 deletions src/badthreads.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef _BADTHREADS_H_
#define _BADTHREADS_H_

/*
* This file contains functions and symbols that are defined in C11 threads.h.
* If any of these symbols are used in a file that includes badthreads.h, it
* should throw an error at compile time.
*
* The purpose of this file is to make sure that code does not accidentally
* use symbols from threads.h. If this happens, and the system C library has
* C11-style thread support, then the resulting object could link to the
* system's functions that have the same name, instead of the local functions.
*/

#define thrd_t THREADS_H_ERROR
Copy link

Choose a reason for hiding this comment

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

This name (thrd_t) still exists even though it's listed here as bad. Pretty sure that means that THREADS_H_ERROR becomes the name of the type, which does mean the wrong type name is avoided, but I'm not sure that's what was intended.

#define thrd_create THREADS_H_ERROR
#define thrd_equal THREADS_H_ERROR
#define thrd_current THREADS_H_ERROR
#define thrd_sleep THREADS_H_ERROR
#define thrd_yield THREADS_H_ERROR
#define thrd_exit THREADS_H_ERROR
#define thrd_detach THREADS_H_ERROR
#define thrd_join THREADS_H_ERROR
#define thrd_success THREADS_H_ERROR
#define thrd_timedout THREADS_H_ERROR
#define thrd_busy THREADS_H_ERROR
#define thrd_nomem THREADS_H_ERROR
#define thrd_error THREADS_H_ERROR
#define thrd_start_t THREADS_H_ERROR
#define mtx_t THREADS_H_ERROR
#define mtx_init THREADS_H_ERROR
#define mtx_lock THREADS_H_ERROR
#define mtx_timedlock THREADS_H_ERROR
#define mtx_trylock THREADS_H_ERROR
#define mtx_unlock THREADS_H_ERROR
#define mtx_destroy THREADS_H_ERROR
#define mtx_plain THREADS_H_ERROR
#define mtx_recursive THREADS_H_ERROR
#define mtx_timed THREADS_H_ERROR
#define call_once THREADS_H_ERROR
#define cnd_t THREADS_H_ERROR
#define cnd_init THREADS_H_ERROR
#define cnd_signal THREADS_H_ERROR
#define cnd_broadcast THREADS_H_ERROR
#define cnd_wait THREADS_H_ERROR
#define cnd_timedwait THREADS_H_ERROR
#define cnd_destroy THREADS_H_ERROR
#define thread_local THREADS_H_ERROR
#define tss_t THREADS_H_ERROR
#define TSS_DTOR_ITERATIONS THREADS_H_ERROR
#define tss_dtor_t THREADS_H_ERROR
#define tss_create THREADS_H_ERROR
#define tss_get THREADS_H_ERROR
#define tss_set THREADS_H_ERROR
#define tss_delete THREADS_H_ERROR


#endif
16 changes: 0 additions & 16 deletions src/c11threads.h

This file was deleted.

2 changes: 1 addition & 1 deletion src/callback_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void testCallbackOrdering() {
}
}

CallbackRegistry::CallbackRegistry() : mutex(mtx_recursive), condvar(mutex) {
CallbackRegistry::CallbackRegistry() : mutex(tct_mtx_recursive), condvar(mutex) {
}

void CallbackRegistry::add(Rcpp::Function func, double secs) {
Expand Down
2 changes: 1 addition & 1 deletion src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// See the Makevars file to see how to compile with various debugging settings.

#if defined(DEBUG_THREAD)
#include "c11threads.h"
#include "tinycthread.h"

extern thrd_t __main_thread__;
extern thrd_t __background_thread__;
Expand Down
2 changes: 1 addition & 1 deletion src/later_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ int dummy_pipe_in, dummy_pipe_out;
bool hot = false;
// This mutex protects reading/writing of `hot` and of reading from/writing to
// the pipe.
Mutex m(mtx_plain);
Mutex m(tct_mtx_plain);

// The buffer we're using for the pipe. This doesn't have to be large,
// in theory it only ever holds zero or one byte.
Expand Down
38 changes: 19 additions & 19 deletions src/threadutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_signed.hpp>

#include "c11threads.h"
#include "tinycthread.h"
#include "timeconv.h"

class ConditionVariable;

class Mutex : boost::noncopyable {
friend class ConditionVariable;
mtx_t _m;
tct_mtx_t _m;

public:
// type must be one of:
Expand All @@ -28,34 +28,34 @@ class Mutex : boost::noncopyable {
//
// (although mtx_timed seems not to be actually implemented)
Mutex(int type) {
if (mtx_init(&_m, type) != thrd_success) {
if (tct_mtx_init(&_m, type) != tct_thrd_success) {
throw std::runtime_error("Mutex creation failed");
}
}

virtual ~Mutex() {
mtx_destroy(&_m);
tct_mtx_destroy(&_m);
}

void lock() {
if (mtx_lock(&_m) != thrd_success) {
if (tct_mtx_lock(&_m) != tct_thrd_success) {
throw std::runtime_error("Mutex failed to lock");
}
}

bool tryLock() {
int res = mtx_trylock(&_m);
if (res == thrd_success) {
int res = tct_mtx_trylock(&_m);
if (res == tct_thrd_success) {
return true;
} else if (res == thrd_busy) {
} else if (res == tct_thrd_busy) {
return false;
} else {
throw std::runtime_error("Mutex failed to trylock");
}
}

void unlock() {
if (mtx_unlock(&_m) != thrd_success) {
if (tct_mtx_unlock(&_m) != tct_thrd_success) {
throw std::runtime_error("Mutex failed to unlock");
}
}
Expand All @@ -75,8 +75,8 @@ class Guard : boost::noncopyable {
};

class ConditionVariable : boost::noncopyable {
mtx_t* _m;
cnd_t _c;
tct_mtx_t* _m;
tct_cnd_t _c;

public:
ConditionVariable(Mutex& mutex) : _m(&mutex._m) {
Expand All @@ -89,28 +89,28 @@ class ConditionVariable : boost::noncopyable {
if (!boost::is_signed<time_t>::value)
throw std::runtime_error("Signed time_t type expected");

if (cnd_init(&_c) != thrd_success)
if (tct_cnd_init(&_c) != tct_thrd_success)
throw std::runtime_error("Condition variable failed to initialize");
}

virtual ~ConditionVariable() {
cnd_destroy(&_c);
tct_cnd_destroy(&_c);
}

// Unblocks one thread (if any are waiting)
void signal() {
if (cnd_signal(&_c) != thrd_success)
if (tct_cnd_signal(&_c) != tct_thrd_success)
throw std::runtime_error("Condition variable failed to signal");
}

// Unblocks all waiting threads
void broadcast() {
if (cnd_broadcast(&_c) != thrd_success)
if (tct_cnd_broadcast(&_c) != tct_thrd_success)
throw std::runtime_error("Condition variable failed to broadcast");
}

void wait() {
if (cnd_wait(&_c, _m) != thrd_success)
if (tct_cnd_wait(&_c, _m) != tct_thrd_success)
throw std::runtime_error("Condition variable failed to wait");
}

Expand All @@ -122,10 +122,10 @@ class ConditionVariable : boost::noncopyable {

ts = addSeconds(ts, timeoutSecs);

int res = cnd_timedwait(&_c, _m, &ts);
if (res == thrd_success) {
int res = tct_cnd_timedwait(&_c, _m, &ts);
if (res == tct_thrd_success) {
return true;
} else if (res == thrd_timedout) {
} else if (res == tct_thrd_timedout) {
return false;
} else {
throw std::runtime_error("Condition variable failed to timedwait");
Expand Down
2 changes: 1 addition & 1 deletion src/timeconv.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// tinycthread.h to provide timespec. Whether tinycthread
// defines timespec or not, we want it to be consistent for
// anyone who uses these functions.
#include "c11threads.h"
#include "tinycthread.h"

inline timespec timevalToTimespec(const timeval& tv) {
timespec ts;
Expand Down
Loading