Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1480)

Unified Diff: fusl/src/aio/aio_suspend.c

Issue 1573973002: Add a "fork" of musl as //fusl. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « fusl/src/aio/aio.c ('k') | fusl/src/aio/lio_listio.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: fusl/src/aio/aio_suspend.c
diff --git a/fusl/src/aio/aio_suspend.c b/fusl/src/aio/aio_suspend.c
new file mode 100644
index 0000000000000000000000000000000000000000..08fb5ddcf1a7b1450fb7446d9e8be202eaa1f42a
--- /dev/null
+++ b/fusl/src/aio/aio_suspend.c
@@ -0,0 +1,79 @@
+#include <aio.h>
+#include <errno.h>
+#include <time.h>
+#include "atomic.h"
+#include "libc.h"
+#include "pthread_impl.h"
+
+extern volatile int __aio_fut;
+
+int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
+{
+ int i, tid = 0, ret, expect = 0;
+ struct timespec at;
+ volatile int dummy_fut, *pfut;
+ int nzcnt = 0;
+ const struct aiocb *cb = 0;
+
+ pthread_testcancel();
+
+ if (cnt<0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (i=0; i<cnt; i++) if (cbs[i]) {
+ if (aio_error(cbs[i]) != EINPROGRESS) return 0;
+ nzcnt++;
+ cb = cbs[i];
+ }
+
+ if (ts) {
+ clock_gettime(CLOCK_MONOTONIC, &at);
+ at.tv_sec += ts->tv_sec;
+ if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) {
+ at.tv_nsec -= 1000000000;
+ at.tv_sec++;
+ }
+ }
+
+ for (;;) {
+ for (i=0; i<cnt; i++)
+ if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+ return 0;
+
+ switch (nzcnt) {
+ case 0:
+ pfut = &dummy_fut;
+ break;
+ case 1:
+ pfut = (void *)&cb->__err;
+ expect = EINPROGRESS | 0x80000000;
+ a_cas(pfut, EINPROGRESS, expect);
+ break;
+ default:
+ pfut = &__aio_fut;
+ if (!tid) tid = __pthread_self()->tid;
+ expect = a_cas(pfut, 0, tid);
+ if (!expect) expect = tid;
+ /* Need to recheck the predicate before waiting. */
+ for (i=0; i<cnt; i++)
+ if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
+ return 0;
+ break;
+ }
+
+ ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts?&at:0, 1);
+
+ switch (ret) {
+ case ETIMEDOUT:
+ ret = EAGAIN;
+ case ECANCELED:
+ case EINTR:
+ errno = ret;
+ return -1;
+ }
+ }
+}
+
+LFS64(aio_suspend);
« no previous file with comments | « fusl/src/aio/aio.c ('k') | fusl/src/aio/lio_listio.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698