Permalink
Browse files

uv: upgrade to ec8c500

  • Loading branch information...
bnoordhuis committed Dec 20, 2011
1 parent 7a4dd50 commit d66ebc0977c2d9f93d03cd2c13d6460b1f4d3fff
View
@@ -38,3 +38,5 @@ Ryan Emery <seebees@gmail.com>
Bruce Mitchener <bruce.mitchener@gmail.com>
Maciej Małecki <maciej.malecki@notimplemented.org>
Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Daisuke Murase <typester@cpan.org>
+Paddy Byers <paddy.byers@gmail.com>
@@ -206,6 +206,28 @@ enum {
EIO_PRI_DEFAULT = 0
};
+#define ETP_PRI_MIN EIO_PRI_MIN
+#define ETP_PRI_MAX EIO_PRI_MAX
+
+#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)
+
+#define ETP_REQ eio_req
+
+/*
+ * a somewhat faster data structure might be nice, but
+ * with 8 priorities this actually needs <20 insns
+ * per shift, the most expensive operation.
+ */
+typedef struct {
+ ETP_REQ *qs[ETP_NUM_PRI], *qe[ETP_NUM_PRI]; /* qstart, qend */
+ int size;
+} etp_reqq;
+
+typedef struct {
+ etp_reqq res_queue; /* queue of outstanding responses for this channel */
+ void *data; /* use this for what you want */
+} eio_channel;
+
/* eio request structure */
/* this structure is mostly read-only */
/* when initialising it, all members must be zero-initialised */
@@ -227,6 +249,8 @@ struct eio_req
long int3; /* chown, fchown: gid */
int errorno; /* errno value on syscall return */
+ eio_channel *channel; /* data used to direct poll callbacks arising from this req */
+
#if __i386 || __amd64
unsigned char cancelled;
#else
@@ -261,11 +285,14 @@ enum {
* and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself).
* done_poll is called when the need to poll is gone.
*/
-int eio_init (void (*want_poll)(void), void (*done_poll)(void));
+int eio_init (void (*want_poll)(eio_channel *), void (*done_poll)(eio_channel *));
+
+/* initialises a channel */
+void eio_channel_init(eio_channel *, void *data);
/* must be called regularly to handle pending requests */
/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
-int eio_poll (void);
+int eio_poll (eio_channel *channel);
/* stop polling if poll took longer than duration seconds */
void eio_set_max_poll_time (eio_tstamp nseconds);
@@ -289,55 +316,55 @@ unsigned int eio_nthreads (void); /* number of worker threads in use currently *
/* convenience wrappers */
#ifndef EIO_NO_WRAPPERS
-eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */
-eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ties a thread for this long, simulating busyness */
-eio_req *eio_sync (int pri, eio_cb cb, void *data);
-eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
-eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
-eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data);
-eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
-eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
-eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
-eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
-eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
-eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data);
-eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
-eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
-eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
-eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
-eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
-eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data);
-eio_req *eio_fchmod (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data);
-eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
-eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data);
-eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data);
-eio_req *eio_open (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data);
-eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
-eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data);
-eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
-eio_req *eio_chmod (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
-eio_req *eio_mkdir (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
-eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
-eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data);
-eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data);
-eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
-eio_req *eio_realpath (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
-eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
-eio_req *eio_mknod (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data);
-eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
-eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
-eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
-eio_req *eio_custom (void (*execute)(eio_req *), int pri, eio_cb cb, void *data);
+eio_req *eio_nop (int pri, eio_cb cb, void *data, eio_channel *channel); /* does nothing except go through the whole process */
+eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data, eio_channel *channel); /* ties a thread for this long, simulating busyness */
+eio_req *eio_sync (int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_close (int fd, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fchmod (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_fchown (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_open (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_chown (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_chmod (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_mkdir (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
+eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
+eio_req *eio_realpath (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* result=ptr2 allocated dynamically */
+eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data, eio_channel *channel); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_mknod (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data, eio_channel *channel);
+eio_req *eio_custom (void (*execute)(eio_req *), int pri, eio_cb cb, void *data, eio_channel *channel);
#endif
/*****************************************************************************/
/* groups */
-eio_req *eio_grp (eio_cb cb, void *data);
+eio_req *eio_grp (eio_cb cb, void *data, eio_channel *channel);
void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit);
void eio_grp_limit (eio_req *grp, int limit);
void eio_grp_add (eio_req *grp, eio_req *req);
@@ -44,6 +44,9 @@ typedef struct {
typedef int uv_file;
+#define UV_ONCE_INIT PTHREAD_ONCE_INIT
+
+typedef pthread_once_t uv_once_t;
typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;
@@ -152,6 +152,16 @@ typedef union {
} fallback_;
} uv_rwlock_t;
+#define UV_ONCE_INIT { 0, NULL, NULL }
+
+typedef struct uv_once_s {
+ unsigned char ran;
+ /* The actual event handle must be aligned to sizeof(HANDLE), so in */
+ /* practice it might overlap padding a little. */
+ HANDLE event;
+ HANDLE padding;
+} uv_once_t;
+
/* Platform-specific definitions for uv_dlopen support. */
typedef HMODULE uv_lib_t;
#define UV_DYNAMIC FAR WINAPI
View
@@ -1339,6 +1339,12 @@ UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
+/* Runs a function once and only once. Concurrent calls to uv_once() with the
+ * same guard will block all callers except one (it's unspecified which one).
+ * The guard should be initialized statically with the UV_ONCE_INIT macro.
+ */
+UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
+
UV_EXTERN int uv_thread_create(uv_thread_t *tid,
void (*entry)(void *arg), void *arg);
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
@@ -1394,6 +1400,8 @@ struct uv_loop_s {
uv_async_t uv_eio_want_poll_notifier;
uv_async_t uv_eio_done_poll_notifier;
uv_idle_t uv_eio_poller;
+ /* Poll result queue */
+ eio_channel uv_eio_channel;
/* Diagnostic counters */
uv_counters_t counters;
/* The last error */
View
@@ -158,10 +158,31 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
}
-uv_loop_t* uv_loop_new(void) {
- uv_loop_t* loop = calloc(1, sizeof(uv_loop_t));
- loop->ev = ev_loop_new(0);
+static int uv__loop_init(uv_loop_t* loop,
+ struct ev_loop *(ev_loop_new)(unsigned int flags)) {
+ memset(loop, 0, sizeof(*loop));
+#if HAVE_KQUEUE
+ loop->ev = ev_loop_new(EVBACKEND_KQUEUE);
+#else
+ loop->ev = ev_loop_new(EVFLAG_AUTO);
+#endif
ev_set_userdata(loop->ev, loop);
+ eio_channel_init(&loop->uv_eio_channel, loop);
+ return 0;
+}
+
+
+uv_loop_t* uv_loop_new(void) {
+ uv_loop_t* loop;
+
+ if ((loop = malloc(sizeof(*loop))) == NULL)
+ return NULL;
+
+ if (uv__loop_init(loop, ev_loop_new)) {
+ free(loop);
+ return NULL;
+ }
+
return loop;
}
@@ -182,16 +203,13 @@ void uv_loop_delete(uv_loop_t* loop) {
uv_loop_t* uv_default_loop(void) {
- if (!default_loop_ptr) {
- default_loop_ptr = &default_loop_struct;
-#if HAVE_KQUEUE
- default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
-#else
- default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
-#endif
- ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
- }
- assert(default_loop_ptr->ev == EV_DEFAULT_UC);
+ if (default_loop_ptr)
+ return default_loop_ptr;
+
+ if (uv__loop_init(&default_loop_struct, ev_default_loop))
+ return NULL;
+
+ default_loop_ptr = &default_loop_struct;
return default_loop_ptr;
}
@@ -692,7 +710,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
uv_ref(loop);
req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
- uv_getaddrinfo_done, handle);
+ uv_getaddrinfo_done, handle, &loop->uv_eio_channel);
assert(req);
assert(req->data == handle);
View
@@ -28,26 +28,47 @@
#include <ifaddrs.h>
#include <net/if.h>
+#include <TargetConditionals.h>
+
+#if !TARGET_OS_IPHONE
#include <CoreServices/CoreServices.h>
+#endif
+
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */
-
static char *process_title;
+#if TARGET_OS_IPHONE
+/* see: http://developer.apple.com/library/mac/#qa/qa1398/_index.html */
+uint64_t uv_hrtime() {
+ uint64_t time;
+ uint64_t enano;
+ static mach_timebase_info_data_t sTimebaseInfo;
+
+ time = mach_absolute_time();
+ if (0 == sTimebaseInfo.denom) {
+ (void)mach_timebase_info(&sTimebaseInfo);
+ }
+
+ enano = time * sTimebaseInfo.numer / sTimebaseInfo.denom;
+
+ return enano;
+}
+#else
uint64_t uv_hrtime() {
uint64_t time;
Nanoseconds enano;
time = mach_absolute_time();
enano = AbsoluteToNanoseconds(*(AbsoluteTime *)&time);
return (*(uint64_t *)&enano);
}
-
+#endif
int uv_exepath(char* buffer, size_t* size) {
uint32_t usize;
Oops, something went wrong.

0 comments on commit d66ebc0

Please sign in to comment.