Class: Nmsg::Socket

Inherits:
Object
  • Object
show all
Defined in:
ext/nmsg/rubyext.c

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(domain, protocol) ⇒ Object



73
74
75
76
77
78
79
80
# File 'ext/nmsg/rubyext.c', line 73

VALUE rb_socket_initialize(VALUE self, VALUE domain, VALUE protocol) {
    GET_SOCKET(self);
    if (!S)
        return Qnil;

    S->fd = nn_socket(NUM2INT(domain), NUM2INT(protocol));
    return self;
}

Class Method Details

.device(so1, so2) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
# File 'ext/nmsg/rubyext.c', line 266

VALUE rb_socket_device(VALUE klass, VALUE so1, VALUE so2) {
    Socket *S1;
    Data_Get_Struct(so1, Socket, S1);

    Socket tmp = { .fd = -1 };
    Socket *S2 = &tmp;

    if (so2 != Qnil) // FIXME
        Data_Get_Struct(so2, Socket, S2);

    return nn_device(S1->fd, S2->fd);
}

.termObject



261
262
263
264
# File 'ext/nmsg/rubyext.c', line 261

VALUE rb_socket_term(VALUE klass) {
    nn_term();
    return klass;
}

Instance Method Details

#bind(addr) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'ext/nmsg/rubyext.c', line 82

VALUE rb_socket_bind(VALUE self, VALUE addr) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    const char *addr_c = StringValueCStr(addr);
    const int endpoint_id = nn_bind(S->fd, addr_c);
    return (endpoint_id == -1) ? Qnil : INT2NUM(endpoint_id);
}

#closeObject



227
228
229
230
231
232
233
234
235
# File 'ext/nmsg/rubyext.c', line 227

VALUE rb_socket_close(VALUE self) {
    GET_SOCKET(self);
    if (S && S->fd > 0) {
        nn_close(S->fd);
        S->fd = -1;
    }

    return self;
}

#connect(addr) ⇒ Object



92
93
94
95
96
97
98
99
100
# File 'ext/nmsg/rubyext.c', line 92

VALUE rb_socket_connect(VALUE self, VALUE addr) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    const char *addr_c = StringValueCStr(addr);
    const int endpoint_id = nn_connect(S->fd, addr_c);
    return (endpoint_id == -1) ? Qnil : INT2NUM(endpoint_id);
}

#get_fdObject



247
248
249
250
# File 'ext/nmsg/rubyext.c', line 247

VALUE rb_socket_get_fd(VALUE self) {
    GET_SOCKET(self);
    return rb_int_new(S->fd);
}

#get_option(level, option) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'ext/nmsg/rubyext.c', line 196

VALUE rb_socket_get_opt(VALUE self, VALUE level, VALUE option) {
    GET_SOCKET(self);
    if (!S || S->fd < 0)
        return Qnil;

    // TODO/FIXME: string values

    int lvl = NUM2INT(level);
    int opt = NUM2INT(option);

    int val = -1;
    size_t sz = sizeof(val);
    const int res = nn_getsockopt(S->fd, lvl, opt, &val, &sz);
    return (res == 0) ? INT2NUM(val) : Qnil;
}

#get_sysfdObject



252
253
254
255
256
257
258
259
# File 'ext/nmsg/rubyext.c', line 252

VALUE rb_socket_get_sysfd(VALUE self) {
    GET_SOCKET(self);

    int optval;
    size_t optval_len = sizeof(int);
    const int res = nn_getsockopt(S->fd, NN_SOL_SOCKET, NN_RCVFD, (void *)&optval, &optval_len);
    return INT2NUM((res == 0) ? optval : -1);
}

#poll(mask, timeout) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'ext/nmsg/rubyext.c', line 102

VALUE rb_socket_poll(VALUE self, VALUE mask, VALUE timeout) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    if (timeout == Qnil)
        timeout = INT2NUM(0);

    struct nn_pollfd pfd;
    pfd.fd = S->fd;
    pfd.events = NUM2INT(mask);

    const int res = nn_poll(&pfd, 1, NUM2INT(timeout));
    if (res == -1) // error
        return Qnil;
    else if (res == 0) // timeout
        return Qfalse;

    return (pfd.revents & NUM2INT(mask)) ? Qtrue : Qfalse;
}

#recv_msgObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'ext/nmsg/rubyext.c', line 123

VALUE rb_socket_recv_msg(VALUE self) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    void *buffer;
    const int nbytes = nn_recv(S->fd, &buffer, NN_MSG, NN_DONTWAIT);
    if (nbytes < 0)
        return Qnil;

    VALUE rs = rb_tainted_str_new(buffer, nbytes);
    nn_freemsg(buffer);

    return rs;
}

#send_msg(obj) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'ext/nmsg/rubyext.c', line 139

VALUE rb_socket_send_msg(VALUE self, VALUE obj) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    const int msg_bytes = RSTRING_LEN(obj);
    const char *data = RSTRING_PTR(obj);
    void *msg = nn_allocmsg(msg_bytes, 0);
    if (!msg)
        return Qnil;
    memcpy(msg, data, msg_bytes);

    const int nbytes = nn_send(S->fd, &msg, NN_MSG, NN_DONTWAIT);
    if (nbytes < 0) {
        nn_freemsg(msg);
        return Qnil;
    }

    return (nbytes == msg_bytes) ? Qtrue : Qfalse;
}

#send_msg_block(obj) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'ext/nmsg/rubyext.c', line 172

VALUE rb_socket_send_msg_block(VALUE self, VALUE obj) {
    GET_SOCKET(self);
    if (!S || S->fd == -1)
        return Qnil;

    const int msg_bytes = RSTRING_LEN(obj);
    const char *data = RSTRING_PTR(obj);
    void *msg = nn_allocmsg(msg_bytes, 0);
    if (!msg)
        return Qnil;
    memcpy(msg, data, msg_bytes);

    struct nogvl_msg wrapper = { S->fd, &msg };
    const int nbytes = (int)rb_thread_call_without_gvl(nogvl_send_msg, &wrapper, RUBY_UBF_IO, 0);
    if (nbytes < 0) {
        nn_freemsg(msg);
        return Qnil;
    }

    return (nbytes == msg_bytes) ? Qtrue : Qfalse;
}

#set_option(level, option, value) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'ext/nmsg/rubyext.c', line 212

VALUE rb_socket_set_opt(VALUE self, VALUE level, VALUE option, VALUE value) {
    GET_SOCKET(self);
    if (!S || S->fd < 0)
        return Qnil;

    // TODO/FIXME: string values

    int lvl = NUM2INT(level);
    int opt = NUM2INT(option);
    int val = NUM2INT(value);

    const int res = nn_setsockopt(S->fd, lvl, opt, &val, sizeof(val));
    return (res == 0) ? self : Qnil;
}

#shutdown(how) ⇒ Object



237
238
239
240
241
242
243
244
245
# File 'ext/nmsg/rubyext.c', line 237

VALUE rb_socket_shutdown(VALUE self, VALUE how) {
    GET_SOCKET(self);
    if (S && S->fd > 0) {
        nn_shutdown(S->fd, NUM2INT(how));
        S->fd = -1;
    }

    return self;
}