uvrb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +17 -0
  2. data/.gitmodules +3 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/Formula/libuv.rb +20 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +24 -0
  8. data/README.rdoc +70 -0
  9. data/Rakefile +29 -0
  10. data/examples/example +0 -0
  11. data/examples/example.c +37 -0
  12. data/examples/example.rb +29 -0
  13. data/examples/example_oop.rb +26 -0
  14. data/examples/python.py +1 -0
  15. data/examples/ruby.rb +1 -0
  16. data/examples/tcp_client_oop.rb +31 -0
  17. data/examples/tcp_example +0 -0
  18. data/examples/tcp_example.c +68 -0
  19. data/examples/tcp_example.rb +41 -0
  20. data/examples/tcp_example_oop.rb +43 -0
  21. data/examples/tcp_example_plain.rb +19 -0
  22. data/examples/tty_example.rb +20 -0
  23. data/features/async.feature +38 -0
  24. data/features/idle.feature +44 -0
  25. data/features/pipe.feature +150 -0
  26. data/features/prepare_and_check.feature +49 -0
  27. data/features/step_definitions/additional_cli_steps.rb +20 -0
  28. data/features/support/env.rb +6 -0
  29. data/lib/uv.rb +248 -0
  30. data/lib/uv/assertions.rb +24 -0
  31. data/lib/uv/async.rb +24 -0
  32. data/lib/uv/check.rb +27 -0
  33. data/lib/uv/error.rb +58 -0
  34. data/lib/uv/file.rb +221 -0
  35. data/lib/uv/file/stat.rb +35 -0
  36. data/lib/uv/filesystem.rb +335 -0
  37. data/lib/uv/fs_event.rb +21 -0
  38. data/lib/uv/handle.rb +65 -0
  39. data/lib/uv/idle.rb +27 -0
  40. data/lib/uv/listener.rb +26 -0
  41. data/lib/uv/loop.rb +326 -0
  42. data/lib/uv/net.rb +31 -0
  43. data/lib/uv/pipe.rb +47 -0
  44. data/lib/uv/prepare.rb +27 -0
  45. data/lib/uv/resource.rb +20 -0
  46. data/lib/uv/stream.rb +105 -0
  47. data/lib/uv/tasks.rb +27 -0
  48. data/lib/uv/tasks/mac.rb +23 -0
  49. data/lib/uv/tasks/unix.rb +23 -0
  50. data/lib/uv/tasks/win.rb +2 -0
  51. data/lib/uv/tcp.rb +162 -0
  52. data/lib/uv/timer.rb +48 -0
  53. data/lib/uv/tty.rb +30 -0
  54. data/lib/uv/types.rb +249 -0
  55. data/lib/uv/types/darwin_x64.rb +10 -0
  56. data/lib/uv/types/linux.rb +6 -0
  57. data/lib/uv/types/unix.rb +12 -0
  58. data/lib/uv/types/windows.rb +13 -0
  59. data/lib/uv/udp.rb +215 -0
  60. data/lib/uv/version.rb +3 -0
  61. data/lib/uvrb.rb +1 -0
  62. data/spec/shared_examples/handle.rb +54 -0
  63. data/spec/shared_examples/stream.rb +109 -0
  64. data/spec/spec_helper.rb +26 -0
  65. data/spec/uv/async_spec.rb +18 -0
  66. data/spec/uv/check_spec.rb +30 -0
  67. data/spec/uv/file_spec.rb +177 -0
  68. data/spec/uv/filesystem_spec.rb +246 -0
  69. data/spec/uv/fs_event_spec.rb +10 -0
  70. data/spec/uv/idle_spec.rb +30 -0
  71. data/spec/uv/loop_spec.rb +241 -0
  72. data/spec/uv/pipe_spec.rb +54 -0
  73. data/spec/uv/prepare_spec.rb +30 -0
  74. data/spec/uv/tcp_spec.rb +134 -0
  75. data/spec/uv/timer_spec.rb +61 -0
  76. data/spec/uv/tty_spec.rb +53 -0
  77. data/spec/uv/udp_spec.rb +190 -0
  78. data/uvrb.gemspec +28 -0
  79. metadata +247 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ html
6
+ pkg
7
+ doc
8
+ tmp
9
+ rerun.txt
10
+ Gemfile.lock
11
+ .bundle
12
+ .idea
13
+ *.rbc
14
+ .yardoc
15
+ bin
16
+ Gemfile-custom
17
+ ext/*
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "ext/libuv"]
2
+ path = ext/libuv
3
+ url = git://github.com/avalanche123/libuv.git
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ branches:
6
+ only:
7
+ - master
8
+ before_install:
9
+ - sudo apt-get install subversion
10
+ - git submodule update --init --recursive
11
+ - echo "yes" | gem uninstall ffi -a
12
+ before_script:
13
+ - rake libuv
data/Formula/libuv.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'formula'
2
+
3
+ class Libuv < Formula
4
+ homepage 'https://github.com/joyent/libuv'
5
+ head 'https://github.com/avalanche123/libuv.git'
6
+
7
+ def install
8
+ system "svn", "co", "http://gyp.googlecode.com/svn/trunk", "build/gyp"
9
+ system './gyp_uv -f xcode -Dtarget_arch=x64'
10
+ system 'xcodebuild', '-project', 'uv.xcodeproj', '-configuration', 'Release', '-target', 'All'
11
+
12
+ cd 'include' do
13
+ include.install Dir['*.h']
14
+ (include+"uv-private").install Dir['uv-private/*.h']
15
+ end
16
+
17
+ lib.install 'build/Release/libuv.a'
18
+ lib.install 'build/Release/libuv.dylib'
19
+ end
20
+ end
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2004-2012 Bulat Shakirzyanov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
21
+ ===
22
+
23
+ This license applies to all parts of uvrb (Ruby FFI bindings for libuv only)
24
+ Libuv itself [is using Node license](https://github.com/joyent/libuv/blob/master/LICENSE)
data/README.rdoc ADDED
@@ -0,0 +1,70 @@
1
+ = uv.rb - libuv FFI bindings for Ruby
2
+ {<img src="https://secure.travis-ci.org/avalanche123/uvrb.png?branch=master" alt="Build Status" />}[http://travis-ci.org/avalanche123/uvrb]
3
+
4
+ {Libuv}[https://github.com/joyent/libuv] is a cross platform asynchronous IO implementation that powers NodeJS. It supports sockets, both UDP and TCP, filesystem operations, TTY, Pipes and other asynchronous primitives like timer, check, prepare and idle.
5
+
6
+ UV.rb is FFI Ruby bindings for libuv.
7
+
8
+ == Usage
9
+
10
+ Create a uv loop or use a default one
11
+
12
+ require 'uv'
13
+
14
+ loop = UV::Loop.default
15
+ # or
16
+ # loop = UV::Loop.new
17
+
18
+ timer = loop.timer
19
+ timer.start(50000, 0) do |error|
20
+ p error if error
21
+ puts "50 seconds passed"
22
+ timer.close
23
+ end
24
+
25
+ loop.run
26
+
27
+ Find more examples in examples directory
28
+
29
+ == Installation
30
+
31
+ gem install uvrb
32
+
33
+ or
34
+
35
+ git clone ...
36
+ cd ...
37
+ bundle install
38
+
39
+ Make sure you have libuv compiled and a shared library (`.dylib`|`.so`|`.dll`) file available in your lib path.
40
+
41
+ To compile libuv from a local submodule version:
42
+
43
+ git submodule update --init
44
+ rake libuv
45
+
46
+ Or to compile libuv on mac, you can install provided Homebrew formula by running:
47
+
48
+ brew install Formula/libuv.rb --HEAD
49
+
50
+ == What's supported
51
+
52
+ * TCP
53
+ * UDP
54
+ * TTY
55
+ * Pipe
56
+ * Timer
57
+ * Prepare
58
+ * Check
59
+ * Idle
60
+ * Async
61
+ * Filesystem
62
+ * File
63
+ * FSEvent
64
+ * Errors
65
+
66
+ == TODO
67
+
68
+ * Port rest of libuv - ares, getaddrinfo, process, work queue, mutexes and locks
69
+ * Tests tests tests
70
+ * Docs docs docs
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ require 'rdoc/task'
8
+ require 'ffi'
9
+ require 'rake/clean'
10
+ require 'uv/tasks'
11
+
12
+ RSpec::Core::RakeTask.new
13
+
14
+ Cucumber::Rake::Task.new(:features)
15
+
16
+ RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force") do |rd|
17
+ rd.main = "README.rdoc"
18
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
19
+ rd.options << "--title=UV.rb - libuv bindings for Ruby"
20
+ rd.options << "--markup=tomdoc"
21
+ end
22
+
23
+ task :test => [:spec, :features]
24
+ task :default => :test
25
+
26
+ desc "Compile libuv from submodule"
27
+ task :libuv => ["ext/libuv.#{FFI::Platform::LIBSUFFIX}"]
28
+
29
+ CLOBBER.include("ext/libuv.#{FFI::Platform::LIBSUFFIX}")
data/examples/example ADDED
Binary file
@@ -0,0 +1,37 @@
1
+ # include <uv.h>
2
+ # include <stdio.h>
3
+
4
+ static int count = 0;
5
+
6
+ void close_cb(uv_handle_t* handle)
7
+ {
8
+ // free(handle);
9
+ }
10
+
11
+ void timer_cb(uv_timer_t* timer, int status)
12
+ {
13
+ puts("1");
14
+ if (count >= 10) {
15
+ // uv_unref(uv_default_loop());
16
+ // uv_timer_stop(timer);
17
+ uv_close((uv_handle_t*)timer, close_cb);
18
+ }
19
+ count++;
20
+ }
21
+
22
+ int main(int argc, char* argv[])
23
+ {
24
+ uv_timer_t timer;
25
+ printf("sizeof timer is %ld\n", sizeof(uv_timer_t));
26
+ printf("sizeof tcp is %ld\n", sizeof(uv_tcp_t));
27
+ printf("sizeof handle is %ld\n", sizeof(uv_handle_t));
28
+ printf("sizeof tty is %ld\n", sizeof(uv_tty_t));
29
+ printf("sizeof udp is %ld\n", sizeof(uv_udp_t));
30
+ // printf("sizeof timer is %ld\n", sizeof(uv_timer_t));
31
+ // printf("sizeof timer is %ld\n", sizeof(uv_timer_t));
32
+
33
+ uv_timer_init(uv_default_loop(), &timer);
34
+ uv_timer_start(&timer, timer_cb, 1, 1);
35
+ uv_run(uv_default_loop());
36
+ uv_loop_delete(uv_default_loop());
37
+ }
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'uvrb'
4
+
5
+ start = Time.now
6
+
7
+ loop = UV.default_loop
8
+
9
+ timer = UV.create_handle(:uv_timer)
10
+ # timer = FFI::MemoryPointer.new(UV::Timer, UV::Timer.size, 1)
11
+ count = 0
12
+ UV.timer_init(loop, timer)
13
+ $stdout << "\r\n"
14
+
15
+ close_cb = proc {|ptr| UV.free(ptr); $stdout << "\n"; }
16
+
17
+ timer_cb = Proc.new do |ptr, status|
18
+ $stdout << "#{count}\r"
19
+ if count >= 10000
20
+ UV.close(ptr, close_cb)
21
+ end
22
+ count += 1
23
+ end
24
+
25
+ UV.timer_start(timer, timer_cb, 1, 1)
26
+ UV.run(loop)
27
+ UV.loop_delete(loop)
28
+
29
+ puts Time.now - start
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'uvrb'
4
+
5
+ start = Time.now
6
+
7
+ loop = UV::Loop.default
8
+
9
+ count = 0
10
+ timer = loop.timer
11
+ $stdout << "\r\n"
12
+
13
+ timer.start(1, 1) do |status|
14
+ $stdout << "\r#{count}"
15
+ if count >= 10000
16
+ timer.close do
17
+ $stdout << "\n"
18
+ end
19
+ end
20
+ count += 1
21
+ end
22
+
23
+ loop.run
24
+ $stdout << "\n"
25
+
26
+ puts Time.now - start
@@ -0,0 +1 @@
1
+ print('hello world')
data/examples/ruby.rb ADDED
@@ -0,0 +1 @@
1
+ puts 'hello world'
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'uvrb'
4
+
5
+ loop = UV::Loop.default
6
+
7
+ client = loop.tcp
8
+
9
+ client.connect("127.0.0.1", 10000) do |err|
10
+ if err
11
+ p err
12
+ exit 1
13
+ end
14
+ client.write("GET /\r\nHost: localhost:10000\r\nAccept: *\r\n\r\n\n") do |err|
15
+ if err
16
+ p err
17
+ exit 1
18
+ end
19
+ client.start_read do |data, err|
20
+ if err
21
+ p err
22
+ exit 1
23
+ end
24
+ puts data
25
+ client.close
26
+ end
27
+ end
28
+ # client.close
29
+ end
30
+
31
+ loop.run
Binary file
@@ -0,0 +1,68 @@
1
+ #include <uv.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+
5
+ #define RESPONSE \
6
+ "HTTP/1.1 200 OK\r\n" \
7
+ "Content-Type: text/plain\r\n" \
8
+ "Content-Length: 12\r\n" \
9
+ "\r\n" \
10
+ "hello world\n"
11
+
12
+ static uv_buf_t resbuf;
13
+
14
+ void on_close(uv_handle_t* handle)
15
+ {
16
+ free(handle);
17
+ }
18
+
19
+ void after_shutdown(uv_shutdown_t* req, int status) {
20
+ free(req);
21
+ uv_close((uv_handle_t*)req->handle, on_close);
22
+ }
23
+
24
+ void after_write(uv_write_t* req, int status) {
25
+ uv_shutdown_t* shutdown_req = malloc(sizeof(uv_shutdown_t));
26
+
27
+ free(req);
28
+ // uv_shutdown(shutdown_req, req->handle, after_shutdown);
29
+ uv_close((uv_handle_t*)req->handle, on_close);
30
+ }
31
+
32
+ void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf)
33
+ {
34
+ uv_write_t* write_req = malloc(sizeof(uv_write_t));
35
+
36
+ uv_write(write_req, tcp, &resbuf, 1, after_write);
37
+ }
38
+
39
+ uv_buf_t on_alloc(uv_handle_t* client, size_t suggested_size)
40
+ {
41
+ return uv_buf_init(malloc(suggested_size), suggested_size);
42
+ }
43
+
44
+ void on_connect(uv_stream_t* server, int status)
45
+ {
46
+ uv_tcp_t* client = malloc(sizeof(uv_tcp_t));
47
+
48
+ uv_tcp_init(uv_default_loop(), client);
49
+ uv_accept(server, (uv_stream_t*) client);
50
+ uv_read_start((uv_stream_t*) client, on_alloc, on_read);
51
+ }
52
+
53
+ int main(int argc, char* argv[])
54
+ {
55
+ uv_tcp_t tcp;
56
+
57
+ resbuf.base = RESPONSE;
58
+ resbuf.len = sizeof(RESPONSE);
59
+
60
+ uv_tcp_init(uv_default_loop(), &tcp);
61
+
62
+ struct sockaddr_in address = uv_ip4_addr("0.0.0.0", 10000);
63
+ uv_tcp_bind(&tcp, address);
64
+ uv_listen((uv_stream_t*)&tcp, 128, on_connect);
65
+
66
+ uv_run(uv_default_loop());
67
+ uv_loop_delete(uv_default_loop());
68
+ }
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'uvrb'
4
+
5
+ def on_read(client, nread, buf)
6
+ if nread == -1
7
+ ptr = UV.last_error(@loop)
8
+ p [UV.err_name(ptr), UV.strerror(ptr)]
9
+ else
10
+ puts buf[:base].read_string(nread)
11
+ end
12
+ UV.free(buf[:base])
13
+ UV.close(client, proc {|client| })
14
+ end
15
+
16
+ def on_alloc(handle, suggested_size)
17
+ UV.buf_init(UV.malloc(suggested_size), suggested_size)
18
+ end
19
+
20
+ def on_connect(server, status)
21
+ client = FFI::AutoPointer.new(UV.create_handle(:uv_tcp), UV.method(:free))
22
+ UV.tcp_init(@loop, client)
23
+
24
+ UV.accept(server, client)
25
+ UV.read_start(client, method(:on_alloc), method(:on_read))
26
+ end
27
+
28
+ def main
29
+ @loop = UV.default_loop
30
+
31
+ server = FFI::AutoPointer.new(UV.create_handle(:uv_tcp), UV.method(:free))
32
+ UV.tcp_init(@loop, server)
33
+
34
+ UV.tcp_bind(server, UV.ip4_addr('0.0.0.0', 10000))
35
+ UV.listen(server, 128, method(:on_connect))
36
+
37
+ UV.run(@loop)
38
+ UV.loop_delete(@loop)
39
+ end
40
+
41
+ main