ever 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ // a single header file is required
2
+ #include <ev.h>
3
+ #include <stdio.h>
4
+ #include <io.h>
5
+
6
+ // every watcher type has its own typedef'd struct
7
+ // with the name ev_TYPE
8
+ ev_io stdin_watcher;
9
+ ev_timer timeout_watcher;
10
+
11
+ // all watcher callbacks have a similar signature
12
+ // this callback is called when data is readable on stdin
13
+ static void
14
+ stdin_cb (EV_P_ ev_io *w, int revents)
15
+ {
16
+ puts ("stdin ready or done or something");
17
+ // for one-shot events, one must manually stop the watcher
18
+ // with its corresponding stop function.
19
+ //ev_io_stop (EV_A_ w);
20
+
21
+ // this causes all nested ev_loop's to stop iterating
22
+ //ev_unloop (EV_A_ EVUNLOOP_ALL);
23
+ }
24
+
25
+ // another callback, this time for a time-out
26
+ static void
27
+ timeout_cb (EV_P_ ev_timer *w, int revents)
28
+ {
29
+ puts ("timeout");
30
+ // this causes the innermost ev_loop to stop iterating
31
+ ev_unloop (EV_A_ EVUNLOOP_ONE);
32
+ }
33
+
34
+
35
+
36
+ #include <winsock.h>
37
+
38
+ #include <stdlib.h>
39
+ #include <iostream>
40
+ int get_server_fd()
41
+ {
42
+
43
+ //----------------------
44
+ // Initialize Winsock.
45
+ WSADATA wsaData;
46
+ int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
47
+ if (iResult != NO_ERROR) {
48
+ printf("Error at WSAStartup()\n");
49
+ return 1;
50
+ }
51
+
52
+ //----------------------
53
+ // Create a SOCKET for listening for
54
+ // incoming connection requests.
55
+ SOCKET ListenSocket;
56
+ ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
57
+ if (ListenSocket == INVALID_SOCKET) {
58
+ printf("Error at socket(): %ld\n", WSAGetLastError());
59
+ WSACleanup();
60
+ return 1;
61
+ }
62
+ printf("socket returned %d\n", ListenSocket);
63
+
64
+ //----------------------
65
+ // The sockaddr_in structure specifies the address family,
66
+ // IP address, and port for the socket that is being bound.
67
+ sockaddr_in service;
68
+ service.sin_family = AF_INET;
69
+ service.sin_addr.s_addr = inet_addr("127.0.0.1");
70
+ service.sin_port = htons(4444);
71
+
72
+ if (bind( ListenSocket,
73
+ (SOCKADDR*) &service,
74
+ sizeof(service)) == SOCKET_ERROR) {
75
+ printf("bind() failed.\n");
76
+ closesocket(ListenSocket);
77
+ WSACleanup();
78
+ return 1;
79
+ }
80
+
81
+ //----------------------
82
+ // Listen for incoming connection requests.
83
+ // on the created socket
84
+ if (listen( ListenSocket, 1 ) == SOCKET_ERROR) {
85
+ printf("Error listening on socket.\n");
86
+ closesocket(ListenSocket);
87
+ WSACleanup();
88
+ return 1;
89
+ }
90
+
91
+
92
+ printf("sock and osf handle are %d %d, error is \n", ListenSocket, _get_osfhandle (ListenSocket)); // -1 is invalid file handle: http://msdn.microsoft.com/en-us/library/ks2530z6.aspx
93
+ printf("err was %d\n", WSAGetLastError());
94
+ //----------------------
95
+ return ListenSocket;
96
+ }
97
+
98
+
99
+ int
100
+ main (void)
101
+ {
102
+ struct ev_loop *loopy = ev_default_loop(0);
103
+ int fd = get_server_fd();
104
+ int fd_real = _open_osfhandle(fd, NULL);
105
+ int conv = _get_osfhandle(fd_real);
106
+ printf("got server fd %d, loop %d, fd_real %d, that converted %d\n", fd, loopy, fd_real, conv);
107
+ // accept(fd, NULL, NULL);
108
+ // initialise an io watcher, then start it
109
+ // this one will watch for stdin to become readable
110
+ ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ conv, EV_READ);
111
+ ev_io_start (loopy, &stdin_watcher);
112
+
113
+ // initialise a timer watcher, then start it
114
+ // simple non-repeating 5.5 second timeout
115
+ //ev_timer_init (&timeout_watcher, timeout_cb, 15.5, 0.);
116
+ //ev_timer_start (loopy, &timeout_watcher);
117
+ printf("starting loop\n");
118
+ // now wait for events to arrive
119
+ ev_loop (loopy, 0);
120
+
121
+ // unloop was called, so exit
122
+ return 0;
123
+ }
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ever
4
+ VERSION = '0.1'
5
+ end
data/lib/ever.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './ever_ext'
data/test/helper.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'fileutils'
6
+ require 'minitest/autorun'
7
+
8
+ module Minitest::Assertions
9
+ def assert_in_range exp_range, act
10
+ msg = message(msg) { "Expected #{mu_pp(act)} to be in range #{mu_pp(exp_range)}" }
11
+ assert exp_range.include?(act), msg
12
+ end
13
+ end
data/test/run.rb ADDED
File without changes
data/test/test_loop.rb ADDED
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+ require 'ever'
5
+
6
+ class LoopTest < MiniTest::Test
7
+ def setup
8
+ super
9
+ @loop = Ever::Loop.new
10
+ end
11
+
12
+ def test_no_watchers
13
+ @loop.emit(1)
14
+ @loop.emit(2)
15
+ @loop.emit(3)
16
+ buf = []
17
+ @loop.each do |key|
18
+ buf << key
19
+ @loop.emit(:stop) if key == 3
20
+ end
21
+ assert_equal [1, 2, 3], buf
22
+ end
23
+
24
+ def test_io
25
+ i, o = IO.pipe
26
+
27
+ @loop.watch_io('foo', i, false, true)
28
+
29
+ o << 'foo'
30
+ buf = []
31
+ @loop.each do |key|
32
+ buf << key
33
+ @loop.stop
34
+ end
35
+
36
+ assert_equal ['foo'], buf
37
+ end
38
+
39
+ def test_cross_thread_signalling
40
+ i, o = IO.pipe
41
+ @loop.watch_io('foo', i, false, true)
42
+
43
+ Thread.new { @loop.signal }
44
+
45
+ event = @loop.next_event
46
+ assert_nil nil, event
47
+ end
48
+
49
+ def test_emit
50
+ i, o = IO.pipe
51
+ @loop.watch_io('foo', i, false, true)
52
+
53
+ Thread.new { o << 'bar'; @loop.emit('baz') }
54
+
55
+ event = @loop.next_event
56
+ assert_equal 'baz', event
57
+
58
+ event = @loop.next_event
59
+ assert_equal 'foo', event
60
+ end
61
+
62
+ def test_timer_oneshot
63
+ @loop.watch_timer('foo', 0.01, 0)
64
+
65
+ t0 = Time.now
66
+ (event = @loop.next_event) until event;
67
+ t1 = Time.now
68
+
69
+ assert_equal 'foo', event
70
+ assert_in_range 0.005..0.02, t1 - t0
71
+ end
72
+
73
+ def test_timer_recurring
74
+ @loop.watch_timer('foo', 0.01, 0.01)
75
+
76
+ t0 = Time.now
77
+ buf = []
78
+ @loop.each do |key|
79
+ buf << Time.now if key == 'foo'
80
+ @loop.stop if buf.size == 3
81
+ end
82
+ t1 = Time.now
83
+
84
+ assert_equal 3, buf.size
85
+ assert_in_range 0.005..0.04, t1 - t0
86
+ end
87
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ever
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Sharon Rosner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-08-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 5.14.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 5.14.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: http_parser.rb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.7.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.7.0
55
+ description:
56
+ email: sharon@noteflakes.com
57
+ executables: []
58
+ extensions:
59
+ - ext/ever/extconf.rb
60
+ extra_rdoc_files:
61
+ - README.md
62
+ files:
63
+ - ".github/workflows/test.yml"
64
+ - ".gitignore"
65
+ - CHANGELOG.md
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - ever.gemspec
72
+ - examples/http_server.rb
73
+ - ext/ever/ever.h
74
+ - ext/ever/ever_ext.c
75
+ - ext/ever/extconf.rb
76
+ - ext/ever/libev.c
77
+ - ext/ever/libev.h
78
+ - ext/ever/loop.c
79
+ - ext/ever/watcher.c
80
+ - ext/libev/Changes
81
+ - ext/libev/LICENSE
82
+ - ext/libev/README
83
+ - ext/libev/README.embed
84
+ - ext/libev/ev.c
85
+ - ext/libev/ev.h
86
+ - ext/libev/ev_epoll.c
87
+ - ext/libev/ev_kqueue.c
88
+ - ext/libev/ev_linuxaio.c
89
+ - ext/libev/ev_poll.c
90
+ - ext/libev/ev_port.c
91
+ - ext/libev/ev_select.c
92
+ - ext/libev/ev_vars.h
93
+ - ext/libev/ev_win32.c
94
+ - ext/libev/ev_wrap.h
95
+ - ext/libev/test_libev_win32.c
96
+ - lib/ever.rb
97
+ - lib/ever/version.rb
98
+ - test/helper.rb
99
+ - test/run.rb
100
+ - test/test_loop.rb
101
+ homepage: https://digital-fabric.github.io/ever
102
+ licenses:
103
+ - MIT
104
+ metadata:
105
+ source_code_uri: https://github.com/digital-fabric/ever
106
+ homepage_uri: https://github.com/digital-fabric/ever
107
+ changelog_uri: https://github.com/digital-fabric/ever/blob/master/CHANGELOG.md
108
+ post_install_message:
109
+ rdoc_options:
110
+ - "--title"
111
+ - ever
112
+ - "--main"
113
+ - README.md
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '2.6'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.1.4
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Callback-less event reactor for Ruby
131
+ test_files: []