New upstream version 0.7.5+dfsg
Andreas Tille
5 years ago
0 | 0 | Package: later |
1 | 1 | Type: Package |
2 | 2 | Title: Utilities for Delaying Function Execution |
3 | Version: 0.7.4 | |
3 | Version: 0.7.5 | |
4 | 4 | Authors@R: c( |
5 | 5 | person("Joe", "Cheng", role = c("aut", "cre"), email = "joe@rstudio.com"), |
6 | 6 | person(family = "RStudio", role = "cph"), |
14 | 14 | License: GPL (>= 2) |
15 | 15 | Imports: Rcpp (>= 0.12.9), rlang |
16 | 16 | LinkingTo: Rcpp, BH |
17 | RoxygenNote: 6.0.1 | |
17 | RoxygenNote: 6.1.0 | |
18 | 18 | Suggests: knitr, rmarkdown, testthat |
19 | 19 | VignetteBuilder: knitr |
20 | 20 | NeedsCompilation: yes |
21 | Packaged: 2018-08-29 23:08:13 UTC; jcheng | |
21 | Packaged: 2018-09-14 22:59:16 UTC; jcheng | |
22 | 22 | Author: Joe Cheng [aut, cre], |
23 | 23 | RStudio [cph], |
24 | 24 | Marcus Geelnard [ctb, cph] (TinyCThread library, |
27 | 27 | https://tinycthread.github.io/) |
28 | 28 | Maintainer: Joe Cheng <joe@rstudio.com> |
29 | 29 | Repository: CRAN |
30 | Date/Publication: 2018-08-31 16:50:03 UTC | |
30 | Date/Publication: 2018-09-18 22:20:03 UTC |
0 | a0eed106e4d50f835114897191007a12 *DESCRIPTION | |
0 | 7d0a13ab83bc9c33390e00bec0bb7ee9 *DESCRIPTION | |
1 | 1 | 75d68761a7804895a64b8af00fe03bf4 *LICENSE.note |
2 | 2 | a61a4f9573261df4683af4d1bb0821b8 *NAMESPACE |
3 | c590dd8769dc8dc5e1147bf1d06c4cb2 *NEWS.md | |
4 | fcda4768ebb5ff7e0497799b03721e69 *R/RcppExports.R | |
3 | 1834d5725d5a205dd0e8cc4389ff0de0 *NEWS.md | |
4 | 1e3ae0bc5d5fb23d17f9533187c2c14e *R/RcppExports.R | |
5 | 5 | e29ede24383cde06ab578cb3b8c843af *R/later.R |
6 | 6 | ec0d146620f0a6071241098cb813b05c *README.md |
7 | 7 | 4004027f97395336c3f55f37c94ef7bd *build/vignette.rds |
9 | 9 | fcabffaf26f1060b0e0ad6588d1d1020 *configure |
10 | 10 | c37ad0d619d6d8eceb3fd7628b145b68 *inst/bgtest.cpp |
11 | 11 | 88133661f44a9f8a51e06a1d8b044372 *inst/doc/later-cpp.Rmd |
12 | d3426bbb4c331041a6a3fca0ef2545b2 *inst/doc/later-cpp.html | |
12 | bd0a73e7358f19a5dd4056e795b1ff8e *inst/doc/later-cpp.html | |
13 | 13 | b036257592c2960388aeed58155f2781 *inst/include/later.h |
14 | 14 | 9a4fb9c64c2be8f09b461fc8cb63b25b *inst/include/later_api.h |
15 | 15 | e63e78b085c72048f8eb51f96eeff220 *man/later.Rd |
18 | 18 | 0e058149a1ea1825f78bbfb8ea52b9cf *man/run_now.Rd |
19 | 19 | b0345186f4ff8f6a32557c287dbbbade *src/Makevars.in |
20 | 20 | 1112afba6d0af79df88285f92177c8ab *src/Makevars.win |
21 | 42a414014c6f21fd5dca6a1066616b4f *src/RcppExports.cpp | |
21 | 4e59533d26a9ca0aa444b4cb47b3932f *src/RcppExports.cpp | |
22 | 22 | 1dd3804fd408876dffff0a34611292f4 *src/c11threads.h |
23 | 6b611f398ea9e3f5f04fcf08769c7432 *src/callback_registry.cpp | |
24 | 21c1284b2473b128389cc898bc2da2ad *src/callback_registry.h | |
23 | 7c7a205a590f500364942a3dab6ce508 *src/callback_registry.cpp | |
24 | 365b5f44d323fcc24f284540e5b20366 *src/callback_registry.h | |
25 | 25 | 2c2a8cec9cef3ad324fa436215b239a3 *src/debug.h |
26 | e37137a0533ebceaf32f5c75fa962804 *src/init.c | |
26 | 5175e822fa69a7de522e497e59933485 *src/init.c | |
27 | 27 | 56792fc6e11c596d958add3d2ce86743 *src/interrupt.h |
28 | 28 | c48e35ccdd1e5c33aa6100505cace605 *src/later.cpp |
29 | 29 | 74456664b74c61e12794cdd833e205dd *src/later.h |
41 | 41 | ce9c1c39ab8f89d7ba25d1cd322cc80e *src/tinycthread/tinycthread.c |
42 | 42 | 671acd3a12564229cbd69d06e12022b3 *src/tinycthread/tinycthread.h |
43 | 43 | 75dd80c5a840af9a913093327ee524d1 *tests/testthat.R |
44 | e3815a99db9ae5f395d494426beb97b9 *tests/testthat/test-run_now.R | |
44 | 28ffcea4f37e4a9e809eee104ddf567b *tests/testthat/test-run_now.R | |
45 | 45 | 88133661f44a9f8a51e06a1d8b044372 *vignettes/later-cpp.Rmd |
0 | ## later 0.7.5 | |
1 | ||
2 | * Fixed issue where the order of callbacks scheduled by native later::later could be nondeterministic if they are scheduled too quickly. This was because callbacks were sorted by the time at which they come due, which could be identical. Later now uses the order of insertion as a tiebreaker. [PR #69](https://github.com/r-lib/later/pull/69) | |
3 | ||
0 | 4 | ## later 0.7.4 |
1 | 5 | |
2 | 6 | * Fixed issue [#45](https://github.com/r-lib/later/issues/45) and [#63](https://github.com/r-lib/later/issues/63): glibc 2.28 and musl (used on Arch and Alpine Linux) added support for C11-style threads.h, which masked functions from the tinycthread library used by later. Later now detects support for threads.h and uses it if available; otherwise it uses tinycthread. [PR #64](https://github.com/r-lib/later/pull/64) |
0 | 0 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand |
1 | 1 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 |
2 | ||
3 | testCallbackOrdering <- function() { | |
4 | invisible(.Call('_later_testCallbackOrdering', PACKAGE = 'later')) | |
5 | } | |
2 | 6 | |
3 | 7 | ensureInitialized <- function() { |
4 | 8 | invisible(.Call('_later_ensureInitialized', PACKAGE = 'later')) |
5 | 5 | |
6 | 6 | using namespace Rcpp; |
7 | 7 | |
8 | // testCallbackOrdering | |
9 | void testCallbackOrdering(); | |
10 | RcppExport SEXP _later_testCallbackOrdering() { | |
11 | BEGIN_RCPP | |
12 | Rcpp::RNGScope rcpp_rngScope_gen; | |
13 | testCallbackOrdering(); | |
14 | return R_NilValue; | |
15 | END_RCPP | |
16 | } | |
8 | 17 | // ensureInitialized |
9 | 18 | void ensureInitialized(); |
10 | 19 | RcppExport SEXP _later_ensureInitialized() { |
0 | #include <boost/atomic.hpp> | |
0 | 1 | #include <boost/bind.hpp> |
1 | 2 | #include <boost/shared_ptr.hpp> |
2 | 3 | #include <boost/make_shared.hpp> |
4 | #include <vector> | |
3 | 5 | #include "callback_registry.h" |
4 | 6 | #include "debug.h" |
7 | ||
8 | boost::atomic<uint64_t> nextCallbackNum(0); | |
9 | ||
10 | Callback::Callback(Timestamp when, Task func) : when(when), func(func) { | |
11 | this->callbackNum = nextCallbackNum++; | |
12 | } | |
13 | ||
14 | // [[Rcpp::export]] | |
15 | void testCallbackOrdering() { | |
16 | std::vector<Callback> callbacks; | |
17 | Timestamp ts; | |
18 | Task func; | |
19 | for (size_t i = 0; i < 100; i++) { | |
20 | callbacks.push_back(Callback(ts, func)); | |
21 | } | |
22 | for (size_t i = 1; i < 100; i++) { | |
23 | if (callbacks[i] < callbacks[i-1]) { | |
24 | ::Rf_error("Callback ordering is broken [1]"); | |
25 | } | |
26 | if (!(callbacks[i] > callbacks[i-1])) { | |
27 | ::Rf_error("Callback ordering is broken [2]"); | |
28 | } | |
29 | if (callbacks[i-1] > callbacks[i]) { | |
30 | ::Rf_error("Callback ordering is broken [3]"); | |
31 | } | |
32 | if (!(callbacks[i-1] < callbacks[i])) { | |
33 | ::Rf_error("Callback ordering is broken [4]"); | |
34 | } | |
35 | } | |
36 | for (size_t i = 100; i > 1; i--) { | |
37 | if (callbacks[i-1] < callbacks[i-2]) { | |
38 | ::Rf_error("Callback ordering is broken [2]"); | |
39 | } | |
40 | } | |
41 | } | |
5 | 42 | |
6 | 43 | CallbackRegistry::CallbackRegistry() : mutex(mtx_recursive), condvar(mutex) { |
7 | 44 | } |
2 | 2 | |
3 | 3 | #include <Rcpp.h> |
4 | 4 | #include <queue> |
5 | #include <boost/operators.hpp> | |
5 | 6 | #include <boost/function.hpp> |
6 | 7 | #include <boost/shared_ptr.hpp> |
7 | 8 | #include "timestamp.h" |
10 | 11 | |
11 | 12 | typedef boost::function0<void> Task; |
12 | 13 | |
13 | class Callback { | |
14 | class Callback : boost::operators<Callback> { | |
14 | 15 | |
15 | 16 | public: |
16 | Callback(Timestamp when, Task func) : when(when), func(func) {} | |
17 | Callback(Timestamp when, Task func); | |
17 | 18 | |
18 | 19 | bool operator<(const Callback& other) const { |
19 | return this->when < other.when; | |
20 | } | |
21 | ||
22 | bool operator>(const Callback& other) const { | |
23 | return this->when > other.when; | |
20 | return this->when < other.when || | |
21 | (!(this->when > other.when) && this->callbackNum < other.callbackNum); | |
24 | 22 | } |
25 | 23 | |
26 | 24 | void operator()() const { |
31 | 29 | |
32 | 30 | private: |
33 | 31 | Task func; |
32 | // Used to break ties when comparing to a callback that has precisely the same | |
33 | // timestamp | |
34 | uint64_t callbackNum; | |
34 | 35 | }; |
35 | 36 | |
36 | 37 | typedef boost::shared_ptr<Callback> Callback_sp; |
12 | 12 | extern SEXP _later_idle(); |
13 | 13 | extern SEXP _later_execLater(SEXP, SEXP); |
14 | 14 | extern SEXP _later_next_op_secs(); |
15 | extern SEXP _later_testCallbackOrdering(); | |
15 | 16 | |
16 | 17 | static const R_CallMethodDef CallEntries[] = { |
17 | {"_later_ensureInitialized", (DL_FUNC) &_later_ensureInitialized, 0}, | |
18 | {"_later_execCallbacks", (DL_FUNC) &_later_execCallbacks, 1}, | |
19 | {"_later_idle", (DL_FUNC) &_later_idle, 0}, | |
20 | {"_later_execLater", (DL_FUNC) &_later_execLater, 2}, | |
21 | {"_later_next_op_secs", (DL_FUNC) &_later_next_op_secs, 0}, | |
18 | {"_later_ensureInitialized", (DL_FUNC) &_later_ensureInitialized, 0}, | |
19 | {"_later_execCallbacks", (DL_FUNC) &_later_execCallbacks, 1}, | |
20 | {"_later_idle", (DL_FUNC) &_later_idle, 0}, | |
21 | {"_later_execLater", (DL_FUNC) &_later_execLater, 2}, | |
22 | {"_later_next_op_secs", (DL_FUNC) &_later_next_op_secs, 0}, | |
23 | {"_later_testCallbackOrdering", (DL_FUNC) &_later_testCallbackOrdering, 0}, | |
22 | 24 | {NULL, NULL, 0} |
23 | 25 | }; |
24 | 26 |
52 | 52 | expect_lt(as.numeric(x[["elapsed"]]), 1.25) |
53 | 53 | expect_true(result) |
54 | 54 | }) |
55 | ||
56 | test_that("When callbacks have tied timestamps, they respect order of creation", { | |
57 | expect_error(testCallbackOrdering(), NA) | |
58 | ||
59 | Rcpp::sourceCpp(code = ' | |
60 | #include <Rcpp.h> | |
61 | #include <later_api.h> | |
62 | ||
63 | void* max_seen = 0; | |
64 | ||
65 | void callback(void* data) { | |
66 | if (data < max_seen) { | |
67 | Rf_error("Bad ordering detected"); | |
68 | } | |
69 | max_seen = data; | |
70 | } | |
71 | ||
72 | // [[Rcpp::depends(later)]] | |
73 | // [[Rcpp::export]] | |
74 | void checkLaterOrdering() { | |
75 | max_seen = 0; | |
76 | for (size_t i = 0; i < 10000; i++) { | |
77 | later::later(callback, (void*)i, 0); | |
78 | } | |
79 | } | |
80 | ') | |
81 | checkLaterOrdering(); while (!later::loop_empty()) later::run_now() | |
82 | }) |