1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
//
// Copyright 2017 Garrett D'Amore <garrett@damore.org>
// Copyright 2017 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
// file was obtained (LICENSE.txt). A copy of the license may also be
// found online at https://opensource.org/licenses/MIT.
//
#ifndef CORE_SOCKET_H
#define CORE_SOCKET_H
// NB: This structure is supplied here for use by the CORE. Use of this library
// OUSIDE of the core is STRICTLY VERBOTEN. NO DIRECT ACCESS BY PROTOCOLS OR
// TRANSPORTS.
struct nni_socket {
nni_mtx s_mx;
nni_cv s_cv;
uint32_t s_id;
nni_msgq *s_uwq; // Upper write queue
nni_msgq *s_urq; // Upper read queue
nni_list_node s_node;
nni_proto_id s_self_id;
nni_proto_id s_peer_id;
uint32_t s_flags;
nni_proto_pipe_ops s_pipe_ops;
nni_proto_sock_ops s_sock_ops;
void *s_data; // Protocol private
// XXX: options
nni_duration s_linger; // linger time
nni_duration s_sndtimeo; // send timeout
nni_duration s_rcvtimeo; // receive timeout
nni_duration s_reconn; // reconnect time
nni_duration s_reconnmax; // max reconnect time
nni_list s_eps; // active endpoints
nni_list s_pipes; // active pipes
size_t s_rcvmaxsz; // maximum receive size
int s_ep_pend; // EP dial/listen in progress
int s_closing; // Socket is closing
int s_closed; // Socket closed
int s_besteffort; // Best effort mode delivery
int s_senderr; // Protocol state machine use
int s_recverr; // Protocol state machine use
nni_event s_recv_ev; // Event for readability
nni_event s_send_ev; // Event for sendability
nni_notifyfd s_send_fd;
nni_notifyfd s_recv_fd;
uint32_t s_nextid; // Next Pipe ID.
};
extern int nni_sock_sys_init(void);
extern void nni_sock_sys_fini(void);
extern int nni_sock_find(nni_sock **, uint32_t);
extern void nni_sock_rele(nni_sock *);
extern int nni_sock_open(nni_sock **, const nni_proto *);
extern void nni_sock_close(nni_sock *);
extern void nni_sock_closeall(void);
extern int nni_sock_shutdown(nni_sock *);
extern uint16_t nni_sock_proto(nni_sock *);
extern uint16_t nni_sock_peer(nni_sock *);
extern int nni_sock_setopt(nni_sock *, int, const void *, size_t);
extern int nni_sock_getopt(nni_sock *, int, void *, size_t *);
extern int nni_sock_recvmsg(nni_sock *, nni_msg **, nni_time);
extern int nni_sock_sendmsg(nni_sock *, nni_msg *, nni_time);
extern int nni_sock_dial(nni_sock *, const char *, nni_ep **, int);
extern int nni_sock_listen(nni_sock *, const char *, nni_ep **, int);
extern uint32_t nni_sock_id(nni_sock *);
extern void nni_sock_lock(nni_sock *);
extern void nni_sock_unlock(nni_sock *);
extern nni_notify *nni_sock_notify(nni_sock *, int, nng_notify_func, void *);
extern void nni_sock_unnotify(nni_sock *, nni_notify *);
extern void nni_sock_ep_remove(nni_sock *, nni_ep *);
// nni_sock_pipe_add adds the pipe to the socket. It is called by
// the generic pipe creation code. It also adds the socket to the
// ep list, and starts the pipe. It does all these to ensure that
// we have complete success or failure, and there is no point where
// a pipe could wind up orphaned.
extern int nni_sock_pipe_add(nni_sock *, nni_ep *, nni_pipe *);
extern void nni_sock_pipe_remove(nni_sock *, nni_pipe *);
// nni_sock_pipe_ready lets the socket know the pipe is ready for
// business. This also calls the socket/protocol specific add function,
// and it may return an error. The reference count should be dropped by
// nni_sock_pipe_closed.
extern int nni_sock_pipe_ready(nni_sock *, nni_pipe *);
// Set error codes for applications. These are only ever
// called from the filter functions in protocols, and thus
// already have the socket lock held.
extern void nni_sock_recverr(nni_sock *, int);
extern void nni_sock_senderr(nni_sock *, int);
// These are socket methods that protocol operations can expect to call.
// Note that each of these should be called without any locks held, since
// the socket can reenter the protocol.
// nni_socket_sendq obtains the upper writeq. The protocol should
// recieve messages from this, and place them on the appropriate pipe.
extern nni_msgq *nni_sock_sendq(nni_sock *);
// nni_socket_recvq obtains the upper readq. The protocol should
// inject incoming messages from pipes to it.
extern nni_msgq *nni_sock_recvq(nni_sock *);
extern nni_duration nni_sock_linger(nni_sock *);
extern size_t nni_sock_rcvmaxsz(nni_sock *);
extern void nni_sock_reconntimes(nni_sock *, nni_duration *, nni_duration *);
#endif // CORE_SOCKET_H
|