asyncengine 0.0.1.testing1 → 0.0.2.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +3 -0
- data/Rakefile +38 -0
- data/asyncengine.gemspec +8 -4
- data/ext/asyncengine/ae_call_from_other_thread.c +106 -0
- data/ext/asyncengine/ae_call_from_other_thread.h +12 -0
- data/ext/asyncengine/ae_handle_common.c +193 -48
- data/ext/asyncengine/ae_handle_common.h +40 -13
- data/ext/asyncengine/ae_ip_utils.c +246 -0
- data/ext/asyncengine/ae_ip_utils.h +25 -0
- data/ext/asyncengine/ae_next_tick.c +81 -21
- data/ext/asyncengine/ae_next_tick.h +4 -2
- data/ext/asyncengine/ae_resolver.c +156 -0
- data/ext/asyncengine/ae_resolver.h +10 -0
- data/ext/asyncengine/ae_tcp.c +908 -0
- data/ext/asyncengine/ae_tcp.h +20 -0
- data/ext/asyncengine/ae_timer.c +355 -81
- data/ext/asyncengine/ae_timer.h +11 -4
- data/ext/asyncengine/ae_udp.c +579 -13
- data/ext/asyncengine/ae_udp.h +15 -2
- data/ext/asyncengine/ae_utils.c +192 -0
- data/ext/asyncengine/ae_utils.h +16 -0
- data/ext/asyncengine/asyncengine_ruby.c +469 -26
- data/ext/asyncengine/asyncengine_ruby.h +49 -11
- data/ext/asyncengine/debug.h +68 -0
- data/ext/asyncengine/extconf.rb +26 -2
- data/ext/asyncengine/ip_parser.c +5954 -0
- data/ext/asyncengine/ip_parser.h +16 -0
- data/ext/asyncengine/libuv/AUTHORS +16 -0
- data/ext/asyncengine/libuv/common.gypi +4 -4
- data/ext/asyncengine/libuv/config-mingw.mk +6 -6
- data/ext/asyncengine/libuv/config-unix.mk +13 -13
- data/ext/asyncengine/libuv/gyp_uv +5 -1
- data/ext/asyncengine/libuv/ibc_tests/exec_test.sh +8 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_shutdown_write_issue.c +171 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_tcp_close_while_connecting.c +102 -0
- data/ext/asyncengine/libuv/include/uv-private/ngx-queue.h +3 -1
- data/ext/asyncengine/libuv/include/uv-private/uv-unix.h +103 -50
- data/ext/asyncengine/libuv/include/uv-private/uv-win.h +76 -24
- data/ext/asyncengine/libuv/include/uv.h +353 -88
- data/ext/asyncengine/libuv/src/ares/ares__close_sockets.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__get_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__read_line.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__timeval.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_cancel.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_data.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_destroy.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_name.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_fds.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyaddr.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyname.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getnameinfo.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getopt.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getsock.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_library_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_llist.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_mkquery.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_nowarn.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_options.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_a_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_aaaa_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_mx_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ns_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ptr_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_srv_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_txt_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_process.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_query.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_search.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_send.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strcasecmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strdup.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strerror.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_timeout.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_version.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_writev.o +0 -0
- data/ext/asyncengine/libuv/src/ares/bitncmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_net_pton.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_ntop.o +0 -0
- data/ext/asyncengine/libuv/src/cares.c +225 -0
- data/ext/asyncengine/libuv/src/cares.o +0 -0
- data/ext/asyncengine/libuv/src/fs-poll.c +237 -0
- data/ext/asyncengine/libuv/src/fs-poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/async.c +78 -17
- data/ext/asyncengine/libuv/src/unix/async.o +0 -0
- data/ext/asyncengine/libuv/src/unix/core.c +305 -213
- data/ext/asyncengine/libuv/src/unix/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/cygwin.c +1 -1
- data/ext/asyncengine/libuv/src/unix/darwin.c +2 -1
- data/ext/asyncengine/libuv/src/unix/dl.c +36 -44
- data/ext/asyncengine/libuv/src/unix/dl.o +0 -0
- data/ext/asyncengine/libuv/src/unix/eio/eio.o +0 -0
- data/ext/asyncengine/libuv/src/unix/error.c +6 -0
- data/ext/asyncengine/libuv/src/unix/error.o +0 -0
- data/ext/asyncengine/libuv/src/unix/ev/ev.c +8 -4
- data/ext/asyncengine/libuv/src/unix/ev/ev.o +0 -0
- data/ext/asyncengine/libuv/src/unix/freebsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/fs.c +25 -33
- data/ext/asyncengine/libuv/src/unix/fs.o +0 -0
- data/ext/asyncengine/libuv/src/unix/internal.h +50 -31
- data/ext/asyncengine/libuv/src/unix/kqueue.c +2 -7
- data/ext/asyncengine/libuv/src/unix/linux/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/inotify.c +12 -14
- data/ext/asyncengine/libuv/src/unix/linux/inotify.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/{core.c → linux-core.c} +1 -1
- data/ext/asyncengine/libuv/src/unix/linux/linux-core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.c +147 -1
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.h +39 -2
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.c +63 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop.c +29 -6
- data/ext/asyncengine/libuv/src/unix/loop.o +0 -0
- data/ext/asyncengine/libuv/src/unix/netbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/openbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/pipe.c +31 -36
- data/ext/asyncengine/libuv/src/unix/pipe.o +0 -0
- data/ext/asyncengine/libuv/src/unix/poll.c +116 -0
- data/ext/asyncengine/libuv/src/unix/poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/process.c +193 -115
- data/ext/asyncengine/libuv/src/unix/process.o +0 -0
- data/ext/asyncengine/libuv/src/unix/stream.c +146 -153
- data/ext/asyncengine/libuv/src/unix/stream.o +0 -0
- data/ext/asyncengine/libuv/src/unix/sunos.c +45 -36
- data/ext/asyncengine/libuv/src/unix/tcp.c +6 -5
- data/ext/asyncengine/libuv/src/unix/tcp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/thread.c +82 -25
- data/ext/asyncengine/libuv/src/unix/thread.o +0 -0
- data/ext/asyncengine/libuv/src/unix/timer.c +69 -58
- data/ext/asyncengine/libuv/src/unix/timer.o +0 -0
- data/ext/asyncengine/libuv/src/unix/tty.c +3 -3
- data/ext/asyncengine/libuv/src/unix/tty.o +0 -0
- data/ext/asyncengine/libuv/src/unix/udp.c +57 -66
- data/ext/asyncengine/libuv/src/unix/udp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/uv-eio.c +33 -50
- data/ext/asyncengine/libuv/src/unix/uv-eio.o +0 -0
- data/ext/asyncengine/libuv/src/uv-common.c +68 -38
- data/ext/asyncengine/libuv/src/uv-common.h +104 -20
- data/ext/asyncengine/libuv/src/uv-common.o +0 -0
- data/ext/asyncengine/libuv/src/win/async.c +20 -17
- data/ext/asyncengine/libuv/src/win/core.c +44 -31
- data/ext/asyncengine/libuv/src/win/dl.c +40 -36
- data/ext/asyncengine/libuv/src/win/error.c +21 -1
- data/ext/asyncengine/libuv/src/win/fs-event.c +19 -21
- data/ext/asyncengine/libuv/src/win/fs.c +541 -189
- data/ext/asyncengine/libuv/src/win/getaddrinfo.c +56 -63
- data/ext/asyncengine/libuv/src/win/handle-inl.h +145 -0
- data/ext/asyncengine/libuv/src/win/handle.c +26 -101
- data/ext/asyncengine/libuv/src/win/internal.h +92 -107
- data/ext/asyncengine/libuv/src/win/loop-watcher.c +6 -14
- data/ext/asyncengine/libuv/src/win/pipe.c +78 -64
- data/ext/asyncengine/libuv/src/win/poll.c +618 -0
- data/ext/asyncengine/libuv/src/win/process-stdio.c +479 -0
- data/ext/asyncengine/libuv/src/win/process.c +147 -274
- data/ext/asyncengine/libuv/src/win/req-inl.h +225 -0
- data/ext/asyncengine/libuv/src/win/req.c +0 -149
- data/ext/asyncengine/libuv/src/{unix/check.c → win/stream-inl.h} +31 -42
- data/ext/asyncengine/libuv/src/win/stream.c +9 -43
- data/ext/asyncengine/libuv/src/win/tcp.c +200 -82
- data/ext/asyncengine/libuv/src/win/thread.c +42 -2
- data/ext/asyncengine/libuv/src/win/threadpool.c +3 -2
- data/ext/asyncengine/libuv/src/win/timer.c +13 -63
- data/ext/asyncengine/libuv/src/win/tty.c +26 -20
- data/ext/asyncengine/libuv/src/win/udp.c +26 -17
- data/ext/asyncengine/libuv/src/win/util.c +312 -167
- data/ext/asyncengine/libuv/src/win/winapi.c +16 -1
- data/ext/asyncengine/libuv/src/win/winapi.h +33 -9
- data/ext/asyncengine/libuv/src/win/winsock.c +88 -1
- data/ext/asyncengine/libuv/src/win/winsock.h +36 -3
- data/ext/asyncengine/libuv/test/benchmark-ares.c +16 -17
- data/ext/asyncengine/libuv/test/benchmark-fs-stat.c +164 -0
- data/ext/asyncengine/libuv/test/benchmark-list.h +9 -0
- data/ext/asyncengine/libuv/{src/unix/prepare.c → test/benchmark-loop-count.c} +42 -33
- data/ext/asyncengine/libuv/test/benchmark-million-timers.c +65 -0
- data/ext/asyncengine/libuv/test/benchmark-pound.c +1 -1
- data/ext/asyncengine/libuv/test/benchmark-sizes.c +2 -0
- data/ext/asyncengine/libuv/test/benchmark-spawn.c +7 -1
- data/ext/asyncengine/libuv/test/benchmark-udp-packet-storm.c +1 -1
- data/ext/asyncengine/libuv/test/echo-server.c +8 -0
- data/ext/asyncengine/libuv/test/run-tests.c +30 -0
- data/ext/asyncengine/libuv/test/runner-unix.c +6 -26
- data/ext/asyncengine/libuv/test/runner-win.c +5 -63
- data/ext/asyncengine/libuv/test/runner.c +10 -1
- data/ext/asyncengine/libuv/test/task.h +0 -8
- data/ext/asyncengine/libuv/test/test-async.c +43 -141
- data/ext/asyncengine/libuv/test/test-callback-order.c +76 -0
- data/ext/asyncengine/libuv/test/test-counters-init.c +2 -3
- data/ext/asyncengine/libuv/test/test-dlerror.c +17 -8
- data/ext/asyncengine/libuv/test/test-fs-event.c +31 -39
- data/ext/asyncengine/libuv/test/test-fs-poll.c +146 -0
- data/ext/asyncengine/libuv/test/test-fs.c +114 -2
- data/ext/asyncengine/libuv/test/test-gethostbyname.c +8 -8
- data/ext/asyncengine/libuv/test/test-hrtime.c +18 -15
- data/ext/asyncengine/libuv/test/test-ipc.c +8 -2
- data/ext/asyncengine/libuv/test/test-list.h +59 -9
- data/ext/asyncengine/libuv/test/test-loop-handles.c +2 -25
- data/ext/asyncengine/libuv/{src/unix/idle.c → test/test-poll-close.c} +37 -39
- data/ext/asyncengine/libuv/test/test-poll.c +573 -0
- data/ext/asyncengine/libuv/test/test-ref.c +79 -63
- data/ext/asyncengine/libuv/test/test-run-once.c +15 -11
- data/ext/asyncengine/libuv/test/test-semaphore.c +111 -0
- data/ext/asyncengine/libuv/test/test-spawn.c +368 -20
- data/ext/asyncengine/libuv/test/test-stdio-over-pipes.c +25 -35
- data/ext/asyncengine/libuv/test/test-tcp-close-while-connecting.c +80 -0
- data/ext/asyncengine/libuv/test/test-tcp-close.c +1 -1
- data/ext/asyncengine/libuv/test/test-tcp-connect-error-after-write.c +95 -0
- data/ext/asyncengine/libuv/test/test-tcp-connect-timeout.c +85 -0
- data/ext/asyncengine/libuv/test/test-tcp-shutdown-after-write.c +131 -0
- data/ext/asyncengine/libuv/test/test-tcp-write-error.c +2 -2
- data/ext/asyncengine/libuv/test/test-tcp-writealot.c +29 -54
- data/ext/asyncengine/libuv/test/test-timer-again.c +1 -1
- data/ext/asyncengine/libuv/test/test-timer.c +23 -1
- data/ext/asyncengine/libuv/test/test-udp-options.c +1 -1
- data/ext/asyncengine/libuv/test/{test-eio-overflow.c → test-walk-handles.c} +31 -44
- data/ext/asyncengine/libuv/uv.gyp +26 -9
- data/ext/asyncengine/rb_utilities.c +54 -0
- data/ext/asyncengine/rb_utilities.h +63 -0
- data/lib/asyncengine.rb +45 -38
- data/lib/asyncengine/asyncengine_ext.so +0 -0
- data/lib/asyncengine/debug.rb +37 -0
- data/lib/asyncengine/handle.rb +9 -0
- data/lib/asyncengine/tcp.rb +28 -0
- data/lib/asyncengine/timer.rb +18 -28
- data/lib/asyncengine/udp.rb +29 -0
- data/lib/asyncengine/utils.rb +32 -0
- data/lib/asyncengine/uv_error.rb +17 -0
- data/lib/asyncengine/version.rb +9 -1
- data/test/ae_test_helper.rb +62 -0
- data/test/test_basic.rb +169 -0
- data/test/test_call_from_other_thread.rb +55 -0
- data/test/test_error.rb +92 -0
- data/test/test_ip_utils.rb +44 -0
- data/test/test_next_tick.rb +37 -0
- data/test/test_resolver.rb +51 -0
- data/test/test_threads.rb +69 -0
- data/test/test_timer.rb +95 -0
- data/test/test_udp.rb +216 -0
- data/test/test_utils.rb +49 -0
- metadata +84 -57
- data/ext/asyncengine/libuv/mkmf.log +0 -24
- data/ext/asyncengine/libuv/src/unix/cares.c +0 -194
- data/ext/asyncengine/libuv/src/unix/cares.o +0 -0
- data/ext/asyncengine/libuv/src/unix/check.o +0 -0
- data/ext/asyncengine/libuv/src/unix/idle.o +0 -0
- data/ext/asyncengine/libuv/src/unix/prepare.o +0 -0
- data/ext/asyncengine/libuv/src/win/cares.c +0 -290
- data/lib/asyncengine/errors.rb +0 -5
- data/lib/asyncengine/next_tick.rb +0 -24
data/README.markdown
CHANGED
data/Rakefile
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "rake/testtask"
|
|
2
|
+
require "rake/clean"
|
|
3
|
+
|
|
4
|
+
AE_EXTEN_DIR = "ext/asyncengine"
|
|
5
|
+
AE_EXTEN_NAME_SO = "asyncengine_ext.so"
|
|
6
|
+
AE_LIB_SO = "lib/asyncengine/asyncengine_ext.so"
|
|
7
|
+
|
|
8
|
+
# Rule to build the extension: this says that the extension should be rebuilt
|
|
9
|
+
# after any change to the files in the extension dir.
|
|
10
|
+
file AE_LIB_SO =>
|
|
11
|
+
Dir.glob("#{AE_EXTEN_DIR}/*{.rb,.c,.h}") do
|
|
12
|
+
Dir.chdir(AE_EXTEN_DIR) do
|
|
13
|
+
ruby "extconf.rb"
|
|
14
|
+
sh "make"
|
|
15
|
+
end
|
|
16
|
+
cp "#{AE_EXTEN_DIR}/#{AE_EXTEN_NAME_SO}", AE_LIB_SO
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Use 'rake clean' and 'rake clobber' to easily delete generated files.
|
|
20
|
+
CLEAN.include("#{AE_EXTEN_DIR}/*{.o,.log,.so,.a}")
|
|
21
|
+
CLEAN.include("#{AE_EXTEN_DIR}/Makefile")
|
|
22
|
+
CLEAN.include(AE_LIB_SO)
|
|
23
|
+
CLOBBER.include("#{AE_EXTEN_DIR}/libuv/**/*{.o,.a}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
task :default => :compile
|
|
27
|
+
|
|
28
|
+
desc "Compile"
|
|
29
|
+
task :compile => AE_LIB_SO
|
|
30
|
+
|
|
31
|
+
Rake::TestTask.new do |t|
|
|
32
|
+
t.libs << "test"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Make the :test task depend on the shared object, so it will be built automatically
|
|
36
|
+
# before running the tests.
|
|
37
|
+
desc "Run tests"
|
|
38
|
+
task :test => AE_LIB_SO
|
data/asyncengine.gemspec
CHANGED
|
@@ -8,19 +8,23 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.date = Time.now
|
|
9
9
|
spec.authors = ["Inaki Baz Castillo"]
|
|
10
10
|
spec.email = "ibc@aliax.net"
|
|
11
|
-
spec.summary = "Ruby asynchronous event driven
|
|
11
|
+
spec.summary = "Ruby asynchronous event driven framework on top of libuv"
|
|
12
12
|
spec.homepage = "https://github.com/ibc/AsyncEngine"
|
|
13
|
-
spec.description = "Ruby asynchronous event driven
|
|
14
|
-
spec.extensions = ["ext/asyncengine/extconf.rb"]
|
|
13
|
+
spec.description = "Ruby asynchronous event driven framework on top of libuv"
|
|
15
14
|
spec.required_ruby_version = ">= 1.9.2"
|
|
16
15
|
|
|
17
16
|
files = %w{
|
|
18
17
|
asyncengine.gemspec
|
|
18
|
+
Rakefile
|
|
19
19
|
README.markdown
|
|
20
|
-
lib
|
|
20
|
+
lib/**/**/**
|
|
21
21
|
ext/asyncengine/{*.c,*.h,*.rb}
|
|
22
22
|
ext/asyncengine/libuv/**/**/**/**/**/**/**/**/**
|
|
23
|
+
test/{ae_test_helper.rb}
|
|
24
|
+
test/{test_*.rb}
|
|
23
25
|
}.join(",")
|
|
26
|
+
|
|
24
27
|
spec.files = Dir.glob "{#{files}}"
|
|
25
28
|
spec.require_paths = ["lib"]
|
|
29
|
+
spec.extensions = ["ext/asyncengine/extconf.rb"]
|
|
26
30
|
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#include "asyncengine_ruby.h"
|
|
2
|
+
#include "ae_handle_common.h"
|
|
3
|
+
#include "ae_call_from_other_thread.h"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
static ID att_call_from_other_thread_procs;
|
|
7
|
+
|
|
8
|
+
static uv_async_t* ae_call_from_other_thread_uv_async;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/** Pre-declaration of static functions. */
|
|
12
|
+
|
|
13
|
+
static void _uv_async_callback(uv_async_t* handle, int status);
|
|
14
|
+
static VALUE _ae_async_callback(void);
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
void init_ae_call_from_other_thread(void)
|
|
18
|
+
{
|
|
19
|
+
AE_TRACE();
|
|
20
|
+
|
|
21
|
+
rb_define_module_function(mAsyncEngine, "call_from_other_thread", AsyncEngine_call_from_other_thread, -1);
|
|
22
|
+
|
|
23
|
+
att_call_from_other_thread_procs = rb_intern("@_call_from_other_thread_procs");
|
|
24
|
+
|
|
25
|
+
ae_call_from_other_thread_uv_async = NULL;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
void load_ae_call_from_other_thread(void)
|
|
30
|
+
{
|
|
31
|
+
AE_TRACE();
|
|
32
|
+
int r;
|
|
33
|
+
|
|
34
|
+
AE_ASSERT(ae_call_from_other_thread_uv_async == NULL);
|
|
35
|
+
|
|
36
|
+
ae_call_from_other_thread_uv_async = ALLOC(uv_async_t);
|
|
37
|
+
r = uv_async_init(AE_uv_loop, ae_call_from_other_thread_uv_async, _uv_async_callback);
|
|
38
|
+
AE_ASSERT(r == 0);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
void unload_ae_call_from_other_thread(void)
|
|
43
|
+
{
|
|
44
|
+
AE_TRACE();
|
|
45
|
+
|
|
46
|
+
AE_ASSERT(ae_call_from_other_thread_uv_async != NULL);
|
|
47
|
+
|
|
48
|
+
AE_CLOSE_UV_HANDLE(ae_call_from_other_thread_uv_async);
|
|
49
|
+
ae_call_from_other_thread_uv_async = NULL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
static
|
|
54
|
+
VALUE AsyncEngine_call_from_other_thread(int argc, VALUE *argv, VALUE self)
|
|
55
|
+
{
|
|
56
|
+
AE_TRACE();
|
|
57
|
+
VALUE proc;
|
|
58
|
+
int r;
|
|
59
|
+
|
|
60
|
+
AE_CHECK_STATUS();
|
|
61
|
+
AE_RB_CHECK_NUM_ARGS(0,1);
|
|
62
|
+
AE_RB_ENSURE_BLOCK_OR_PROC(1, proc);
|
|
63
|
+
|
|
64
|
+
rb_ary_push(rb_ivar_get(mAsyncEngine, att_call_from_other_thread_procs), proc);
|
|
65
|
+
r = uv_async_send(ae_call_from_other_thread_uv_async);
|
|
66
|
+
AE_ASSERT(r == 0);
|
|
67
|
+
|
|
68
|
+
return Qtrue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
static
|
|
73
|
+
void _uv_async_callback(uv_async_t* handle, int status)
|
|
74
|
+
{
|
|
75
|
+
AE_TRACE();
|
|
76
|
+
|
|
77
|
+
ae_take_gvl_and_run_with_error_handler(_ae_async_callback);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
static
|
|
82
|
+
VALUE _ae_async_callback(void)
|
|
83
|
+
{
|
|
84
|
+
AE_TRACE();
|
|
85
|
+
VALUE procs;
|
|
86
|
+
long i;
|
|
87
|
+
|
|
88
|
+
AE_ASSERT(AE_status == AE_RUNNING);
|
|
89
|
+
|
|
90
|
+
// procs = @_call_from_other_thread_procs
|
|
91
|
+
procs = rb_ivar_get(mAsyncEngine, att_call_from_other_thread_procs);
|
|
92
|
+
// @_call_from_other_thread_procs = []
|
|
93
|
+
rb_ivar_set(mAsyncEngine, att_call_from_other_thread_procs, rb_ary_new());
|
|
94
|
+
|
|
95
|
+
// Iterate procs Array and call each proc.
|
|
96
|
+
for(i=0 ; i<RARRAY_LEN(procs) ; i++) {
|
|
97
|
+
// It could occur that one of these procs is a release_loop() method, so
|
|
98
|
+
// stop iterating.
|
|
99
|
+
if (AE_status != AE_RUNNING)
|
|
100
|
+
break;
|
|
101
|
+
ae_run_with_error_handler(ae_proc_call_0, rb_ary_entry(procs, i));
|
|
102
|
+
}
|
|
103
|
+
procs = Qnil;
|
|
104
|
+
|
|
105
|
+
return Qnil;
|
|
106
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#ifndef AE_CALL_FROM_OTHER_THREAD_H
|
|
2
|
+
#define AE_CALL_FROM_OTHER_THREAD_H
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
void init_ae_call_from_other_thread(void);
|
|
6
|
+
void load_ae_call_from_other_thread_uv_async(void);
|
|
7
|
+
void unload_ae_call_from_other_thread_uv_async(void);
|
|
8
|
+
|
|
9
|
+
static VALUE AsyncEngine_call_from_other_thread(int argc, VALUE *argv, VALUE self);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#endif /* AE_CALL_FROM_OTHER_THREAD_H */
|
|
@@ -2,99 +2,244 @@
|
|
|
2
2
|
#include "ae_handle_common.h"
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
|
|
5
|
+
// Ruby modules/classes.
|
|
6
|
+
static VALUE mKernel;
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
static
|
|
8
|
+
// Ruby method names.
|
|
9
|
+
static ID method_call;
|
|
10
|
+
static ID method_handle_error;
|
|
11
|
+
static ID method_raise;
|
|
10
12
|
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
+
// C variable holding current proc number.
|
|
14
|
+
static long proc_long_id;
|
|
13
15
|
|
|
14
|
-
// Ruby attributes.
|
|
15
|
-
static ID att_blocks;
|
|
16
|
-
ID att_cdata;
|
|
17
|
-
ID att_handle_terminated;
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
void init_ae_handle_common(void)
|
|
18
|
+
{
|
|
19
|
+
AE_TRACE();
|
|
20
|
+
|
|
21
|
+
mKernel = rb_define_module("Kernel");
|
|
22
|
+
|
|
23
|
+
method_call = rb_intern("call");
|
|
24
|
+
method_handle_error = rb_intern("handle_error");
|
|
25
|
+
method_raise = rb_intern("raise");
|
|
26
|
+
|
|
27
|
+
proc_long_id = 0;
|
|
28
|
+
}
|
|
22
29
|
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
VALUE ae_store_handle(VALUE ae_handle)
|
|
25
32
|
{
|
|
26
|
-
|
|
33
|
+
AE_TRACE();
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
att_handle_terminated = rb_intern("@_handle_terminated");
|
|
35
|
+
VALUE ae_handle_id = rb_obj_id(ae_handle);
|
|
36
|
+
rb_hash_aset(AE_handles, ae_handle_id, ae_handle);
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
id_manage_exception = rb_intern("manage_exception");
|
|
38
|
+
return ae_handle_id;
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
|
|
37
|
-
VALUE
|
|
42
|
+
VALUE ae_get_handle(VALUE ae_handle_id)
|
|
38
43
|
{
|
|
39
44
|
AE_TRACE();
|
|
40
|
-
VALUE rb_block_id = LONG2FIX(++block_id);
|
|
41
45
|
|
|
42
|
-
|
|
43
|
-
return rb_block_id;
|
|
46
|
+
return rb_hash_aref(AE_handles, ae_handle_id);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
|
|
47
|
-
VALUE
|
|
50
|
+
VALUE ae_remove_handle(VALUE ae_handle_id)
|
|
48
51
|
{
|
|
49
52
|
AE_TRACE();
|
|
50
|
-
|
|
53
|
+
|
|
54
|
+
return rb_hash_delete(AE_handles, ae_handle_id);
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
|
|
54
|
-
VALUE
|
|
58
|
+
VALUE ae_store_proc(VALUE proc)
|
|
55
59
|
{
|
|
56
60
|
AE_TRACE();
|
|
57
|
-
|
|
61
|
+
|
|
62
|
+
VALUE proc_id = LONG2FIX(++proc_long_id);
|
|
63
|
+
rb_hash_aset(AE_procs, proc_id, proc);
|
|
64
|
+
|
|
65
|
+
return proc_id;
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
|
|
61
|
-
|
|
69
|
+
VALUE ae_get_proc(VALUE proc_id)
|
|
62
70
|
{
|
|
63
71
|
AE_TRACE();
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
return rb_hash_aref(AE_procs, proc_id);
|
|
74
|
+
}
|
|
67
75
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
else
|
|
76
|
-
rb_jump_tag(exception_tag);
|
|
76
|
+
|
|
77
|
+
VALUE ae_remove_proc(VALUE proc_id)
|
|
78
|
+
{
|
|
79
|
+
AE_TRACE();
|
|
80
|
+
|
|
81
|
+
return rb_hash_delete(AE_procs, proc_id);
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
|
|
80
|
-
void
|
|
85
|
+
void ae_uv_handle_close_callback(uv_handle_t* handle)
|
|
81
86
|
{
|
|
82
87
|
AE_TRACE();
|
|
88
|
+
|
|
83
89
|
xfree(handle);
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
int ae_get_last_uv_error_int(void)
|
|
94
|
+
{
|
|
95
|
+
AE_TRACE();
|
|
96
|
+
|
|
97
|
+
return uv_last_error(AE_uv_loop).code;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
VALUE ae_get_uv_error(int uv_errno)
|
|
102
|
+
{
|
|
103
|
+
AE_TRACE();
|
|
104
|
+
|
|
105
|
+
VALUE ae_uv_error;
|
|
106
|
+
|
|
107
|
+
if (NIL_P(ae_uv_error = rb_hash_aref(AE_UV_ERRORS, INT2FIX(uv_errno))))
|
|
108
|
+
ae_uv_error = rb_hash_aref(AE_UV_ERRORS, INT2FIX(-1));
|
|
109
|
+
|
|
110
|
+
return ae_uv_error;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
VALUE ae_get_last_uv_error(void)
|
|
115
|
+
{
|
|
116
|
+
AE_TRACE();
|
|
117
|
+
|
|
118
|
+
VALUE ae_uv_error;
|
|
119
|
+
|
|
120
|
+
if (NIL_P(ae_uv_error = rb_hash_aref(AE_UV_ERRORS, INT2FIX(uv_last_error(AE_uv_loop).code))))
|
|
121
|
+
ae_uv_error = rb_hash_aref(AE_UV_ERRORS, INT2FIX(-1));
|
|
122
|
+
|
|
123
|
+
return ae_uv_error;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
void ae_raise_uv_error(int uv_errno)
|
|
128
|
+
{
|
|
129
|
+
AE_TRACE();
|
|
130
|
+
|
|
131
|
+
VALUE ae_uv_error = ae_get_uv_error(uv_errno);
|
|
132
|
+
|
|
133
|
+
rb_funcall2(mKernel, method_raise, 1, &ae_uv_error);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
void ae_raise_last_uv_error(void)
|
|
88
138
|
{
|
|
89
|
-
|
|
90
|
-
|
|
139
|
+
AE_TRACE();
|
|
140
|
+
|
|
141
|
+
VALUE ae_uv_error = ae_get_last_uv_error();
|
|
142
|
+
|
|
143
|
+
rb_funcall2(mKernel, method_raise, 1, &ae_uv_error);
|
|
91
144
|
}
|
|
92
145
|
|
|
93
146
|
|
|
94
|
-
|
|
147
|
+
VALUE ae_proc_call_0(VALUE proc)
|
|
95
148
|
{
|
|
96
|
-
|
|
149
|
+
AE_TRACE();
|
|
97
150
|
|
|
98
|
-
|
|
99
|
-
return
|
|
151
|
+
AE_ASSERT(! NIL_P(proc));
|
|
152
|
+
return rb_funcall2(proc, method_call, 0, NULL);
|
|
100
153
|
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
VALUE ae_proc_call_1(VALUE proc, VALUE param)
|
|
157
|
+
{
|
|
158
|
+
AE_TRACE();
|
|
159
|
+
|
|
160
|
+
AE_ASSERT(! NIL_P(proc));
|
|
161
|
+
return rb_funcall2(proc, method_call, 1, ¶m);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
VALUE ae_proc_call_2(VALUE proc, VALUE param1, VALUE param2)
|
|
166
|
+
{
|
|
167
|
+
AE_TRACE();
|
|
168
|
+
|
|
169
|
+
AE_ASSERT(! NIL_P(proc));
|
|
170
|
+
return rb_funcall(proc, method_call, 2, param1, param2);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
VALUE ae_proc_call_3(VALUE proc, VALUE param1, VALUE param2, VALUE param3)
|
|
175
|
+
{
|
|
176
|
+
AE_TRACE();
|
|
177
|
+
|
|
178
|
+
AE_ASSERT(! NIL_P(proc));
|
|
179
|
+
return rb_funcall(proc, method_call, 3, param1, param2, param3);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
/*
|
|
184
|
+
* When any AsyncEngine handler runs a handle method having the GVL,
|
|
185
|
+
* it must use this function, which can receive an optional VALUE parameter.
|
|
186
|
+
*/
|
|
187
|
+
VALUE ae_run_with_error_handler(void* function, VALUE param)
|
|
188
|
+
{
|
|
189
|
+
AE_TRACE();
|
|
190
|
+
|
|
191
|
+
VALUE ret, error;
|
|
192
|
+
int error_tag;
|
|
193
|
+
|
|
194
|
+
if (param)
|
|
195
|
+
ret = rb_protect(function, (VALUE)param, &error_tag);
|
|
196
|
+
else
|
|
197
|
+
ret = rb_protect(function, Qnil, &error_tag);
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
* If an error occurs while in function() it can be due:
|
|
201
|
+
*
|
|
202
|
+
* - An Exception (including SystemExit), this is "rescue-able" via "rescue Exception"
|
|
203
|
+
* and will run the "ensure" code if present. In this case rb_errinfo() returns the
|
|
204
|
+
* exact Exception object.
|
|
205
|
+
*
|
|
206
|
+
* - A Thread#kill. This is NOT "rescue-able" via "rescue Exception" but it WILL run
|
|
207
|
+
* the "ensure" code if present. In this case rb_errinfo() returns FIXNUM 8.
|
|
208
|
+
*
|
|
209
|
+
* So, check the class of the object returned by rb_errinfo(). If it's an Exception then
|
|
210
|
+
* store it, release the loop and raise it. Otherwise (Thread#kill) then don't store the
|
|
211
|
+
* exception returned by rb_errinfo() and just release the loop. Ruby will do the rest.
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
if (error_tag) {
|
|
215
|
+
// TODO: This could return Fixnum 8: https://github.com/ibc/AsyncEngine/issues/4,
|
|
216
|
+
// so the error handler must check it. Maybe it's better to set error=Qnil and
|
|
217
|
+
// pass it to the error handler? NO, let's ae_handle_error(error) to do it.
|
|
218
|
+
error = rb_errinfo();
|
|
219
|
+
rb_set_errinfo(Qnil);
|
|
220
|
+
AE_DEBUG("error class: %s", rb_obj_classname(error));
|
|
221
|
+
|
|
222
|
+
// NOTE: This function should never been called when releasing.
|
|
223
|
+
if (AE_status == AE_RELEASING)
|
|
224
|
+
AE_ABORT("error (class: %s) rescued while in releasing status", rb_obj_classname(error)); // TODO: testing, not sure yet.
|
|
225
|
+
|
|
226
|
+
AE_DEBUG("error (class: %s) rescued, passing it to the error handler", rb_obj_classname(error));
|
|
227
|
+
ae_handle_error(error);
|
|
228
|
+
return Qnil;
|
|
229
|
+
}
|
|
230
|
+
else
|
|
231
|
+
return ret;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
* When any AsyncEngine handler runs a Ruby callback, it must
|
|
237
|
+
* use this function, which must be called without the GVL.
|
|
238
|
+
* TODO: Allow passing a VALUE parameter...?
|
|
239
|
+
*/
|
|
240
|
+
VALUE ae_take_gvl_and_run_with_error_handler(void* function)
|
|
241
|
+
{
|
|
242
|
+
AE_TRACE();
|
|
243
|
+
|
|
244
|
+
return rb_thread_call_with_gvl(ae_run_with_error_handler, function);
|
|
245
|
+
}
|