erlix 0.5.0a

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,27 @@
1
+ #!/usr/bin/ruby
2
+ #-*- ruby -*-
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ findei=File.join(File.dirname(__FILE__),"findei.erl")
8
+ File.chmod(0755,findei)
9
+ ei_dir=`#{findei}`.chomp
10
+ src_dir=File.join(File.dirname(__FILE__),"src")
11
+ mkmf=File.join(File.dirname(__FILE__),"extconf.rb")
12
+ cmd=[
13
+ "ruby #{mkmf}",
14
+ "--with-ei-dir=#{ei_dir}",
15
+ "--with-cflags=\"-std=c99\"",
16
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
17
+ "--srcdir=#{src_dir}"].join(" ")
18
+
19
+ env=[
20
+ "--with-ei-dir=#{ei_dir}",
21
+ "--with-cflags=\"-std=c99\"",
22
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
23
+ "--srcdir=#{src_dir}"].join(" ")
24
+ puts cmd
25
+ puts `#{cmd}`
26
+
27
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby
2
+ #-*- ruby -*-
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ findei=File.join(File.dirname(__FILE__),"findei.erl")
8
+ File.chmod(0755,findei)
9
+ ei_dir=`#{findei}`.chomp
10
+ src_dir=File.join(File.dirname(__FILE__),"src")
11
+ mkmf=File.join(File.dirname(__FILE__),"extconf.rb")
12
+ cmd=[
13
+ "ruby #{mkmf}",
14
+ "--with-ei-dir=#{ei_dir}",
15
+ "--with-cflags=\"-std=c99\"",
16
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
17
+ "--srcdir=#{src_dir}"].join(" ")
18
+
19
+ env=[
20
+ "--with-ei-dir=#{ei_dir}",
21
+ "--with-cflags=\"-std=c99\"",
22
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
23
+ "--srcdir=#{src_dir}"].join(" ")
24
+ puts cmd
25
+ puts `#{cmd}`
26
+
27
+
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ require "mkmf"
8
+
9
+ dir_config("ei")
10
+
11
+ if have_library("ei","erl_init") and
12
+ have_library("erl_interface","erl_init")
13
+ then
14
+ create_makefile("erlix")
15
+ else
16
+ puts "error: erl_interface not found!"
17
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env escript
2
+ %%% Author : KDr2
3
+ %%% Find the location of erl_interface.
4
+
5
+ main(_) ->
6
+ io:format("~s~n", [code:lib_dir(erl_interface)]).
@@ -0,0 +1,30 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+ #include <stdlib.h>
7
+
8
+ #include "erlix_term.h"
9
+
10
+
11
+
12
+
13
+ void Init_erlix(){
14
+ VALUE mod_erlix;
15
+ mod_erlix=rb_define_module("Erlix");
16
+ erl_init(NULL,0);
17
+ init_erlix_term(mod_erlix);
18
+ init_erlix_int(mod_erlix);
19
+ init_erlix_uint(mod_erlix);
20
+ init_erlix_float(mod_erlix);
21
+ init_erlix_pid(mod_erlix);
22
+ init_erlix_ref(mod_erlix);
23
+ init_erlix_atom(mod_erlix);
24
+ init_erlix_list(mod_erlix);
25
+ init_erlix_node(mod_erlix);
26
+ init_erlix_tuple(mod_erlix);
27
+ init_erlix_binary(mod_erlix);
28
+ init_erlix_message(mod_erlix);
29
+ init_erlix_connection(mod_erlix);
30
+ }
@@ -0,0 +1,62 @@
1
+ /* -*- c-*-
2
+ *
3
+ * project : erlix
4
+ * author : KDr2
5
+ *
6
+ */
7
+
8
+ #include "erlix_term.h"
9
+
10
+ VALUE erlix_cErlixAtom;
11
+
12
+ VALUE erlix_atom_alloc(VALUE klass){
13
+ ErlixTerm* atom;
14
+ VALUE obj;
15
+ atom=new_erlix_term();
16
+ atom->type=TYPE_ATOM;
17
+ obj=Data_Wrap_Struct(klass,0,free_erlix_term,atom);
18
+ return obj;
19
+ }
20
+
21
+ static VALUE erlix_atom_init(VALUE self,VALUE string){
22
+ ErlixTerm* atom;
23
+ VALUE str=StringValue(string);
24
+ Data_Get_Struct(self,ErlixTerm,atom);
25
+ atom->term=erl_mk_atom(RSTRING_PTR(str));
26
+ return self;
27
+ }
28
+
29
+
30
+ static VALUE erlix_atom_size(VALUE self){
31
+ ErlixTerm *atom;
32
+ int l;
33
+ Data_Get_Struct(self,ErlixTerm,atom);
34
+ l=ERL_ATOM_SIZE(atom->term);
35
+ return INT2FIX(l);
36
+ }
37
+
38
+ static VALUE erlix_atom_inspect(VALUE self){
39
+ VALUE ret=rb_str_new2("#<Erlix::Atom:");
40
+ ID concat=rb_intern("concat");
41
+ rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
42
+ rb_funcall(ret,concat,1,rb_str_new2(">"));
43
+ return ret;
44
+ }
45
+
46
+ static VALUE erlix_atom_etype(VALUE self){
47
+ return rb_str_new2("atom");
48
+ }
49
+
50
+ void init_erlix_atom(VALUE erlix){
51
+ erlix_cErlixAtom=rb_define_class_under(erlix,"Atom",rb_cObject);
52
+
53
+ rb_define_alloc_func(erlix_cErlixAtom,erlix_atom_alloc);
54
+ rb_define_method(erlix_cErlixAtom,"initialize",erlix_atom_init,1);
55
+ rb_define_method(erlix_cErlixAtom,"size",erlix_atom_size,0);
56
+ rb_define_method(erlix_cErlixAtom,"etype",erlix_atom_etype,0);
57
+ rb_define_method(erlix_cErlixAtom,"inspect",erlix_atom_inspect,0);
58
+
59
+ rb_include_module(erlix_cErlixAtom,erlix_mErlixTerm);
60
+ }
61
+
62
+
@@ -0,0 +1,67 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+
7
+ #include "erlix_term.h"
8
+
9
+ VALUE erlix_cErlixBinary;
10
+
11
+ VALUE erlix_binary_alloc(VALUE klass){
12
+ ErlixTerm* binary;
13
+ VALUE obj;
14
+ binary=new_erlix_term();
15
+ binary->type=TYPE_BINARY;
16
+ obj=Data_Wrap_Struct(klass,0,free_erlix_term,binary);
17
+ return obj;
18
+ }
19
+
20
+ static VALUE erlix_binary_init(VALUE self,VALUE string){
21
+ ErlixTerm* binary;
22
+ VALUE str=StringValue(string);
23
+ Data_Get_Struct(self,ErlixTerm,binary);
24
+ //TODO length limit
25
+ binary->term=erl_mk_binary(RSTRING_PTR(str),(uint32_t)RSTRING_LEN(str));
26
+ return self;
27
+ }
28
+
29
+
30
+ static VALUE erlix_binary_data(VALUE self){
31
+ ErlixTerm* binary;
32
+ Data_Get_Struct(self,ErlixTerm,binary);
33
+ return rb_str_new(ERL_BIN_PTR(binary->term),ERL_BIN_SIZE(binary->term));
34
+ }
35
+
36
+ static VALUE erlix_binary_size(VALUE self){
37
+ ErlixTerm *binary;
38
+ int l;
39
+ Data_Get_Struct(self,ErlixTerm,binary);
40
+ l=ERL_BIN_SIZE(binary->term);
41
+ return INT2FIX(l);
42
+ }
43
+
44
+ static VALUE erlix_binary_inspect(VALUE self){
45
+ VALUE ret=rb_str_new2("#<Erlix::Binary:");
46
+ ID concat=rb_intern("concat");
47
+ rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
48
+ rb_funcall(ret,concat,1,rb_str_new2(">"));
49
+ return ret;
50
+ }
51
+
52
+ static VALUE erlix_binary_etype(VALUE self){
53
+ return rb_str_new2("binary");
54
+ }
55
+
56
+ void init_erlix_binary(VALUE erlix){
57
+ erlix_cErlixBinary=rb_define_class_under(erlix, "Binary",rb_cObject);
58
+
59
+ rb_define_alloc_func(erlix_cErlixBinary,erlix_binary_alloc);
60
+ rb_define_method(erlix_cErlixBinary,"initialize",erlix_binary_init,1);
61
+ rb_define_method(erlix_cErlixBinary,"data",erlix_binary_data,0);
62
+ rb_define_method(erlix_cErlixBinary,"size",erlix_binary_size,0);
63
+ rb_define_method(erlix_cErlixBinary,"inspect",erlix_binary_inspect,0);
64
+ rb_define_method(erlix_cErlixBinary,"etype",erlix_binary_etype,0);
65
+
66
+ rb_include_module(erlix_cErlixBinary,erlix_mErlixTerm);
67
+ }
@@ -0,0 +1,247 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+
7
+ #include <unistd.h>
8
+ #include <stdlib.h>
9
+
10
+ #include "erlix_term.h"
11
+ #include "erlix_node.h"
12
+ #include "erlix_connection.h"
13
+
14
+ extern ErlixNode* erlix_node;
15
+ extern VALUE erlix_cErlixMessage;
16
+
17
+ VALUE erlix_cErlixConnection;
18
+
19
+ ErlixConnection* new_erlix_connection(){
20
+ ErlixConnection* ret=(ErlixConnection*)malloc(sizeof(ErlixConnection));
21
+ ret->status=0;
22
+ return ret;
23
+ }
24
+
25
+ void free_erlix_connection(void *econ){
26
+ ErlixConnection* ep=econ;
27
+ ERLIX_CONNECTION_DEAD(ep);
28
+ erl_close_connection(ep->sock_fd);
29
+ free(ep);
30
+ }
31
+
32
+ VALUE erlix_connection_alloc(VALUE klass){
33
+ ErlixConnection* ec=new_erlix_connection();
34
+ VALUE obj;
35
+ obj=Data_Wrap_Struct(klass,0,free_erlix_connection,ec);
36
+ return obj;
37
+ }
38
+
39
+ static VALUE erlix_connection_init(VALUE self,VALUE pnode){
40
+ VALUE node;
41
+ int sockfd;
42
+ ErlixConnection *conn;
43
+
44
+ if(erlix_node==NULL){
45
+ rb_raise(rb_eException,"call Erlix::Node.init(name,cookie) first please!");
46
+ return Qnil;
47
+ }
48
+ node=StringValue(pnode);
49
+ if((sockfd = erl_connect(RSTRING_PTR(node)))<0){
50
+ rb_raise(rb_eException,"erl_connect failed");
51
+ return Qnil;
52
+ }
53
+
54
+ Data_Get_Struct(self,ErlixConnection,conn);
55
+ conn->peer_node=rb_str_new2(RSTRING_PTR(node));
56
+ conn->sock_fd=sockfd;
57
+ ERLIX_CONNECTION_BORN(conn);
58
+ return self;
59
+ }
60
+
61
+
62
+ static VALUE erlix_connection_init_copy(VALUE copy,VALUE orig){
63
+ ErlixConnection *tcopy,*tsrc;
64
+
65
+ if(copy==orig)return copy;
66
+ if(TYPE(orig)!=T_DATA||RDATA(orig)->dfree!=(RUBY_DATA_FUNC)free_erlix_connection){
67
+ rb_raise(rb_eTypeError,"wrong argument type!");
68
+ }
69
+
70
+ Data_Get_Struct(copy,ErlixConnection,tcopy);
71
+ Data_Get_Struct(orig,ErlixConnection,tsrc);
72
+
73
+ if(!ERLIX_CONNECTION_ALIVE(tsrc)){
74
+ rb_raise(rb_eException,"the connection has been disconnected!");
75
+ return Qnil;
76
+ }
77
+
78
+ tcopy->status=tsrc->status;
79
+ tcopy->peer_node=rb_str_new2(RSTRING_PTR(tsrc->peer_node));
80
+ tcopy->sock_fd=tsrc->sock_fd;
81
+
82
+ return copy;
83
+ }
84
+
85
+
86
+ static VALUE erlix_connection_to_str(VALUE self);
87
+
88
+ //peer node name
89
+ static VALUE erlix_connection_peer(VALUE self){
90
+ ErlixConnection *con;
91
+ Data_Get_Struct(self,ErlixConnection,con);
92
+ if(!ERLIX_CONNECTION_ALIVE(con)){
93
+ rb_raise(rb_eException,"the connection has been disconnected!");
94
+ return Qnil;
95
+ }
96
+ return con->peer_node;
97
+ }
98
+
99
+ static VALUE erlix_connection_etype(VALUE self){
100
+ return rb_str_new2("erlix_connection");
101
+ }
102
+
103
+ static VALUE erlix_connection_mkpid(VALUE self);
104
+
105
+ static VALUE erlix_connection_send(VALUE self,VALUE pid,VALUE term){
106
+ ErlixConnection *con;
107
+ ErlixTerm * ep;
108
+
109
+ if(!IS_ETERM(term)){
110
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixTerm!");
111
+ return Qnil;
112
+ }
113
+ Data_Get_Struct(self,ErlixConnection,con);
114
+ Data_Get_Struct(term,ErlixTerm,ep);
115
+ if(!ERLIX_CONNECTION_ALIVE(con)){
116
+ rb_raise(rb_eException,"the connection has been disconnected!");
117
+ return Qnil;
118
+ }
119
+ if(TYPE(pid)==T_STRING){
120
+ if(erl_reg_send(con->sock_fd,RSTRING_PTR(pid),ep->term)==1){
121
+ return term;
122
+ }else if(erl_errno==EIO){
123
+ ERLIX_CONNECTION_DEAD(con);
124
+ rb_raise(rb_eException,"IO Error!");
125
+ return Qnil;
126
+ }
127
+ }
128
+ return Qnil;
129
+ }
130
+
131
+ extern int rb_io_wait_readable(int);
132
+
133
+ static VALUE erlix_connection_recv(VALUE self){
134
+ ErlixConnection *con;
135
+ ErlMessage emsg;
136
+
137
+ Data_Get_Struct(self,ErlixConnection,con);
138
+
139
+ if(!ERLIX_CONNECTION_ALIVE(con)){
140
+ rb_raise(rb_eException,"the connection has been disconnected!");
141
+ return Qnil;
142
+ }
143
+ for(;;){
144
+ //bugfixed! for 1.8.7 thread block!
145
+ if(rb_io_wait_readable(con->sock_fd)!=Qtrue){
146
+ rb_thread_wait_fd(con->sock_fd);
147
+ }
148
+ int ret;
149
+ VALUE m;
150
+ ErlMessage *newm;
151
+
152
+ ret=erl_receive_msg(con->sock_fd,NULL,0,&emsg);
153
+ if (ret == ERL_MSG) {
154
+ m=erlix_message_alloc(erlix_cErlixMessage);
155
+ Data_Get_Struct(m,ErlMessage,newm);
156
+ newm->type=emsg.type;
157
+ if(emsg.type==ERL_SEND){
158
+ newm->msg=erl_copy_term(emsg.msg);
159
+ newm->to=erl_copy_term(emsg.to);
160
+ }else if(emsg.type==ERL_REG_SEND){
161
+ newm->msg=erl_copy_term(emsg.msg);
162
+ newm->from=erl_copy_term(emsg.from);
163
+ }else if(emsg.type==ERL_LINK ||emsg.type==ERL_UNLINK){
164
+ newm->from=erl_copy_term(emsg.from);
165
+ newm->to=erl_copy_term(emsg.to);
166
+ }else if(emsg.type==ERL_EXIT){
167
+ newm->msg=erl_copy_term(emsg.msg);
168
+ newm->from=erl_copy_term(emsg.from);
169
+ newm->to=erl_copy_term(emsg.to);
170
+ }
171
+ memcpy(newm->to_name,emsg.to_name,MAXREGLEN);
172
+ return m;
173
+ }else if(ret == ERL_TICK){
174
+ continue;
175
+ }else{
176
+ rb_raise(rb_eException,"receive error!");
177
+ return Qnil;
178
+ }
179
+ }
180
+ return Qnil;
181
+ }
182
+
183
+ static VALUE erlix_connection_rpc(VALUE self,VALUE module,VALUE func,VALUE args){
184
+
185
+ VALUE m;
186
+ VALUE f;
187
+ ErlixTerm* a;
188
+ ErlixConnection *con;
189
+ ETERM *result;
190
+
191
+ m=StringValue(module);
192
+ f=StringValue(func);
193
+ if(!IS_ETERM(args)){
194
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixList!");
195
+ return Qnil;
196
+ }
197
+ Data_Get_Struct(args,ErlixTerm,a);
198
+ if(a->type!=TYPE_LIST){
199
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixList!");
200
+ return Qnil;
201
+ }
202
+ Data_Get_Struct(self,ErlixConnection,con);
203
+ result=erl_rpc(con->sock_fd, RSTRING_PTR(m),RSTRING_PTR(f), a->term);
204
+ if(result==NULL){
205
+ if(erl_errno==ENOMEM){
206
+ rb_raise(rb_eException,"rpc error: no memory");
207
+ }else if(erl_errno==EIO){
208
+ rb_raise(rb_eException,"rpc error: I/O error");
209
+ }else if(erl_errno==ETIMEDOUT){
210
+ rb_raise(rb_eException,"rpc error: timeout");
211
+ }else if(erl_errno==EAGAIN){
212
+ rb_raise(rb_eException,"rpc error: Temporary error, Try again");
213
+ }
214
+ return Qnil;
215
+ }
216
+ return erlix_term(result);
217
+ }
218
+
219
+ static VALUE erlix_connection_close(VALUE self){
220
+ ErlixConnection *con;
221
+ Data_Get_Struct(self,ErlixConnection,con);
222
+ ERLIX_CONNECTION_DEAD(con);
223
+ close(con->sock_fd);
224
+ return Qtrue;
225
+ }
226
+
227
+ static VALUE erlix_connection_isclosed(VALUE self){
228
+ ErlixConnection *con;
229
+ Data_Get_Struct(self,ErlixConnection,con);
230
+ if(ERLIX_CONNECTION_ALIVE(con)){
231
+ return Qfalse;
232
+ }
233
+ return Qtrue;
234
+ }
235
+
236
+ void init_erlix_connection(VALUE erlix){
237
+ erlix_cErlixConnection=rb_define_class_under(erlix,"Connection",rb_cObject);
238
+ rb_define_alloc_func(erlix_cErlixConnection,erlix_connection_alloc);
239
+ rb_define_method(erlix_cErlixConnection,"initialize",erlix_connection_init,1);
240
+ rb_define_method(erlix_cErlixConnection,"initialize_copy",erlix_connection_init_copy,1);
241
+ rb_define_method(erlix_cErlixConnection,"peer",erlix_connection_peer,0);
242
+ rb_define_method(erlix_cErlixConnection,"esend",erlix_connection_send,2);
243
+ rb_define_method(erlix_cErlixConnection,"erecv",erlix_connection_recv,0);
244
+ rb_define_method(erlix_cErlixConnection,"rpc",erlix_connection_rpc,3);
245
+ rb_define_method(erlix_cErlixConnection,"close",erlix_connection_close,0);
246
+ rb_define_method(erlix_cErlixConnection,"closed?",erlix_connection_isclosed,0);
247
+ }