ever 0.1

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.
@@ -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: []