Add libsockevent: a socket event dispatching library
This library provides an event-based abstraction model and dispatching facility for socket drivers. Its main goal is to eliminate any and all need for socket drivers to keep track of pending socket calls. Additionally, this library takes over responsibility of a number of other tasks that would otherwise be duplicated between socket drivers, but in such a way that individual socket drivers retain a large degree of freedom in terms of API behavior. The library's main features are: - suspension, resumption, and cancellation of socket calls; - an abstraction layer for select(2); - state tracking of shutdown(2); - pending (asynchronous) errors and the SO_ERROR socket option; - listening-socket tracking and the SO_ACCEPTCONN socket option; - generation of SIGPIPE signals; SO_NOSIGPIPE, MSG_NOSIGNAL; - send and receive low-watermark tracking, SO_SNDLOWAT, SO_RCVLOWAT; - send and receive timeout support and SO_SNDTIMEO, SO_RCVTIMEO; - an abstraction layer for the SO_LINGER socket option; - tracking of various on/off socket options as well as SO_TYPE; - a range of pre-checks on socket calls that are required POSIX. In order to track per-socket state, the library manages an opaque "sock" object for each socket. The allocation of such objects is left entirely to the socket driver. Each sock object has an associated callback table for calls from libsockevent to the socket driver. The socket driver can raise events on the sock object in order to flag that any previously suspended operations of a particular type should be resumed. The library may defer processing such raised events if immediate processing could interfere with internal consistency. The sockevent library is layered on top of libsockdriver, and should be used by all socket driver implementations if at all possible. Change-Id: I3eb2c80602a63ef13035f646473360293607ab76
This commit is contained in:
parent
85723df033
commit
4c27a83389
@ -1239,6 +1239,7 @@
|
|||||||
./usr/include/minix/sef.h minix-comp
|
./usr/include/minix/sef.h minix-comp
|
||||||
./usr/include/minix/sffs.h minix-comp
|
./usr/include/minix/sffs.h minix-comp
|
||||||
./usr/include/minix/sockdriver.h minix-comp
|
./usr/include/minix/sockdriver.h minix-comp
|
||||||
|
./usr/include/minix/sockevent.h minix-comp
|
||||||
./usr/include/minix/sound.h minix-comp
|
./usr/include/minix/sound.h minix-comp
|
||||||
./usr/include/minix/spin.h minix-comp
|
./usr/include/minix/spin.h minix-comp
|
||||||
./usr/include/minix/sys_config.h minix-comp
|
./usr/include/minix/sys_config.h minix-comp
|
||||||
@ -1931,6 +1932,7 @@
|
|||||||
./usr/lib/bc/libsaslc.a minix-comp bitcode
|
./usr/lib/bc/libsaslc.a minix-comp bitcode
|
||||||
./usr/lib/bc/libsffs.a minix-comp bitcode
|
./usr/lib/bc/libsffs.a minix-comp bitcode
|
||||||
./usr/lib/bc/libsockdriver.a minix-comp bitcode
|
./usr/lib/bc/libsockdriver.a minix-comp bitcode
|
||||||
|
./usr/lib/bc/libsockevent.a minix-comp bitcode
|
||||||
./usr/lib/bc/libsqlite3.a minix-comp bitcode
|
./usr/lib/bc/libsqlite3.a minix-comp bitcode
|
||||||
./usr/lib/bc/libssl.a minix-comp bitcode
|
./usr/lib/bc/libssl.a minix-comp bitcode
|
||||||
./usr/lib/bc/libsys.a minix-comp bitcode
|
./usr/lib/bc/libsys.a minix-comp bitcode
|
||||||
@ -2092,6 +2094,8 @@
|
|||||||
./usr/lib/libsffs_pic.a minix-comp
|
./usr/lib/libsffs_pic.a minix-comp
|
||||||
./usr/lib/libsockdriver.a minix-comp
|
./usr/lib/libsockdriver.a minix-comp
|
||||||
./usr/lib/libsockdriver_pic.a minix-comp
|
./usr/lib/libsockdriver_pic.a minix-comp
|
||||||
|
./usr/lib/libsockevent.a minix-comp
|
||||||
|
./usr/lib/libsockevent_pic.a minix-comp
|
||||||
./usr/lib/libsqlite3.a minix-comp
|
./usr/lib/libsqlite3.a minix-comp
|
||||||
./usr/lib/libsqlite3_pic.a minix-comp
|
./usr/lib/libsqlite3_pic.a minix-comp
|
||||||
./usr/lib/libstdc++.a minix-comp libstdcxx
|
./usr/lib/libstdc++.a minix-comp libstdcxx
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
./usr/lib/libsaslc_g.a minix-debug debuglib
|
./usr/lib/libsaslc_g.a minix-debug debuglib
|
||||||
./usr/lib/libsffs_g.a minix-debug debuglib
|
./usr/lib/libsffs_g.a minix-debug debuglib
|
||||||
./usr/lib/libsockdriver_g.a minix-debug debuglib
|
./usr/lib/libsockdriver_g.a minix-debug debuglib
|
||||||
|
./usr/lib/libsockevent_g.a minix-debug debuglib
|
||||||
./usr/lib/libsqlite3_g.a minix-debug debuglib
|
./usr/lib/libsqlite3_g.a minix-debug debuglib
|
||||||
./usr/lib/libssl_g.a minix-debug debuglib
|
./usr/lib/libssl_g.a minix-debug debuglib
|
||||||
./usr/lib/libstdc++_g.a minix-debug libstdcxx,debuglib
|
./usr/lib/libstdc++_g.a minix-debug libstdcxx,debuglib
|
||||||
|
@ -37,6 +37,7 @@ SUBDIR+= ../minix/lib/libasyn \
|
|||||||
../minix/lib/libnetdriver \
|
../minix/lib/libnetdriver \
|
||||||
../minix/lib/libsffs \
|
../minix/lib/libsffs \
|
||||||
../minix/lib/libsockdriver \
|
../minix/lib/libsockdriver \
|
||||||
|
../minix/lib/libsockevent \
|
||||||
../minix/lib/libtimers \
|
../minix/lib/libtimers \
|
||||||
../minix/lib/libusb \
|
../minix/lib/libusb \
|
||||||
../minix/lib/libvtreefs
|
../minix/lib/libvtreefs
|
||||||
|
@ -17,7 +17,8 @@ INCS+= acpi.h audio_fw.h bitmap.h \
|
|||||||
netdriver.h optset.h padconf.h partition.h portio.h \
|
netdriver.h optset.h padconf.h partition.h portio.h \
|
||||||
priv.h procfs.h profile.h queryparam.h \
|
priv.h procfs.h profile.h queryparam.h \
|
||||||
rmib.h rs.h safecopies.h sched.h sef.h sffs.h \
|
rmib.h rs.h safecopies.h sched.h sef.h sffs.h \
|
||||||
sockdriver.h sound.h spin.h sys_config.h sysctl.h sysinfo.h \
|
sockdriver.h sockevent.h sound.h spin.h \
|
||||||
|
sys_config.h sysctl.h sysinfo.h \
|
||||||
syslib.h sysutil.h timers.h type.h \
|
syslib.h sysutil.h timers.h type.h \
|
||||||
u64.h usb.h usb_ch9.h vbox.h \
|
u64.h usb.h usb_ch9.h vbox.h \
|
||||||
vboxfs.h vboxif.h vboxtype.h vm.h \
|
vboxfs.h vboxif.h vboxtype.h vm.h \
|
||||||
|
120
minix/include/minix/sockevent.h
Normal file
120
minix/include/minix/sockevent.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#ifndef _MINIX_SOCKEVENT_H
|
||||||
|
#define _MINIX_SOCKEVENT_H
|
||||||
|
|
||||||
|
#include <minix/sockdriver.h>
|
||||||
|
|
||||||
|
/* Socket events. */
|
||||||
|
#define SEV_BIND 0x01 /* a pending bind operation has ended */
|
||||||
|
#define SEV_CONNECT 0x02 /* a pending connect operation has ended */
|
||||||
|
#define SEV_ACCEPT 0x04 /* pending accept operations may be resumed */
|
||||||
|
#define SEV_SEND 0x08 /* pending send operations may be resumed */
|
||||||
|
#define SEV_RECV 0x10 /* pending receive operations may be resumed */
|
||||||
|
#define SEV_CLOSE 0x20 /* a pending close operation has ended */
|
||||||
|
|
||||||
|
/* Socket flags. */
|
||||||
|
#define SFL_SHUT_RD 0x01 /* socket has been shut down for reading */
|
||||||
|
#define SFL_SHUT_WR 0x02 /* socket has been shut down for writing */
|
||||||
|
#define SFL_CLOSING 0x04 /* socket close operation in progress */
|
||||||
|
#define SFL_CLONED 0x08 /* socket has been cloned but not accepted */
|
||||||
|
#define SFL_TIMER 0x10 /* socket is on list of timers */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special return value from sop_recv callback functions. This pseudo-value
|
||||||
|
* is used to differentiate between zero-sized packets and actual EOF.
|
||||||
|
*/
|
||||||
|
#define SOCKEVENT_EOF 1
|
||||||
|
|
||||||
|
struct sockevent_ops;
|
||||||
|
struct sockevent_proc;
|
||||||
|
|
||||||
|
/* Socket structure. None of its fields must ever be accessed directly. */
|
||||||
|
struct sock {
|
||||||
|
sockid_t sock_id; /* socket identifier */
|
||||||
|
unsigned char sock_events; /* pending events (SEV_) */
|
||||||
|
unsigned char sock_flags; /* internal flags (SFL_) */
|
||||||
|
unsigned char sock_domain; /* domain, address family (PF_, AF_) */
|
||||||
|
int sock_type; /* type: stream, datagram.. (SOCK_) */
|
||||||
|
int sock_err; /* pending error code < 0, 0 if none */
|
||||||
|
unsigned int sock_opt; /* generic option flags (SO_) */
|
||||||
|
clock_t sock_linger; /* SO_LINGER value, in ticks or time */
|
||||||
|
clock_t sock_stimeo; /* SO_SNDTIMEO value, in clock ticks */
|
||||||
|
clock_t sock_rtimeo; /* SO_RCVTIMEO value, in clock ticks */
|
||||||
|
size_t sock_slowat; /* SO_SNDLOWAT value, in bytes */
|
||||||
|
size_t sock_rlowat; /* SO_RCVLOWAT value, in bytes */
|
||||||
|
const struct sockevent_ops *sock_ops; /* socket operations table */
|
||||||
|
SIMPLEQ_ENTRY(sock) sock_next; /* list for pending events */
|
||||||
|
SLIST_ENTRY(sock) sock_hash; /* list for hash table */
|
||||||
|
SLIST_ENTRY(sock) sock_timer; /* list of socks with timers */
|
||||||
|
struct sockevent_proc *sock_proc; /* list of suspended calls */
|
||||||
|
struct sockdriver_select sock_select; /* pending select query */
|
||||||
|
unsigned int sock_selops; /* pending select operations, or 0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Socket operations table. */
|
||||||
|
struct sockevent_ops {
|
||||||
|
int (* sop_pair)(struct sock * sock1, struct sock * sock2,
|
||||||
|
endpoint_t user_endpt);
|
||||||
|
int (* sop_bind)(struct sock * sock, const struct sockaddr * addr,
|
||||||
|
socklen_t addr_len, endpoint_t user_endpt);
|
||||||
|
int (* sop_connect)(struct sock * sock, const struct sockaddr * addr,
|
||||||
|
socklen_t addr_len, endpoint_t user_endpt);
|
||||||
|
int (* sop_listen)(struct sock * sock, int backlog);
|
||||||
|
sockid_t (* sop_accept)(struct sock * sock, struct sockaddr * addr,
|
||||||
|
socklen_t * addr_len, endpoint_t user_endpt,
|
||||||
|
struct sock ** newsockp);
|
||||||
|
int (* sop_test_accept)(struct sock * sock);
|
||||||
|
int (* sop_pre_send)(struct sock * sock, size_t len, socklen_t ctl_len,
|
||||||
|
const struct sockaddr * addr, socklen_t addr_len,
|
||||||
|
endpoint_t user_endpt, int flags);
|
||||||
|
int (* sop_send)(struct sock * sock,
|
||||||
|
const struct sockdriver_data * data, size_t len, size_t * off,
|
||||||
|
const struct sockdriver_data * ctl, socklen_t ctl_len,
|
||||||
|
socklen_t * ctl_off, const struct sockaddr * addr,
|
||||||
|
socklen_t addr_len, endpoint_t user_endpt, int flags, size_t min);
|
||||||
|
int (* sop_test_send)(struct sock * sock, size_t min);
|
||||||
|
int (* sop_pre_recv)(struct sock * sock, endpoint_t user_endpt,
|
||||||
|
int flags);
|
||||||
|
int (* sop_recv)(struct sock * sock,
|
||||||
|
const struct sockdriver_data * data, size_t len, size_t * off,
|
||||||
|
const struct sockdriver_data * ctl, socklen_t ctl_len,
|
||||||
|
socklen_t * ctl_off, struct sockaddr * addr, socklen_t * addr_len,
|
||||||
|
endpoint_t user_endpt, int flags, size_t min, int * rflags);
|
||||||
|
int (* sop_test_recv)(struct sock * sock, size_t min, size_t * size);
|
||||||
|
int (* sop_ioctl)(struct sock * sock, unsigned long request,
|
||||||
|
const struct sockdriver_data * data, endpoint_t user_endpt);
|
||||||
|
void (* sop_setsockmask)(struct sock * sock, unsigned int mask);
|
||||||
|
int (* sop_setsockopt)(struct sock * sock, int level, int name,
|
||||||
|
const struct sockdriver_data * data, socklen_t len);
|
||||||
|
int (* sop_getsockopt)(struct sock * sock, int level, int name,
|
||||||
|
const struct sockdriver_data * data, socklen_t * len);
|
||||||
|
int (* sop_getsockname)(struct sock * sock, struct sockaddr * addr,
|
||||||
|
socklen_t * addr_len);
|
||||||
|
int (* sop_getpeername)(struct sock * sock, struct sockaddr * addr,
|
||||||
|
socklen_t * addr_len);
|
||||||
|
int (* sop_shutdown)(struct sock * sock, unsigned int flags);
|
||||||
|
int (* sop_close)(struct sock * sock, int force);
|
||||||
|
void (* sop_free)(struct sock * sock);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef sockid_t (* sockevent_socket_cb_t)(int domain, int type, int protocol,
|
||||||
|
endpoint_t user_endpt, struct sock ** sock,
|
||||||
|
const struct sockevent_ops ** ops);
|
||||||
|
|
||||||
|
void sockevent_init(sockevent_socket_cb_t socket_cb);
|
||||||
|
void sockevent_process(const message * m_ptr, int ipc_status);
|
||||||
|
|
||||||
|
void sockevent_clone(struct sock * sock, struct sock * newsock,
|
||||||
|
sockid_t newid);
|
||||||
|
|
||||||
|
void sockevent_raise(struct sock * sock, unsigned int mask);
|
||||||
|
void sockevent_set_error(struct sock * sock, int err);
|
||||||
|
void sockevent_set_shutdown(struct sock * sock, unsigned int flags);
|
||||||
|
|
||||||
|
#define sockevent_get_domain(sock) ((int)((sock)->sock_domain))
|
||||||
|
#define sockevent_get_type(sock) ((sock)->sock_type)
|
||||||
|
#define sockevent_get_opt(sock) ((sock)->sock_opt)
|
||||||
|
#define sockevent_is_listening(sock) (!!((sock)->sock_opt & SO_ACCEPTCONN))
|
||||||
|
#define sockevent_is_shutdown(sock, mask) ((sock)->sock_flags & (mask))
|
||||||
|
#define sockevent_is_closing(sock) (!!((sock)->sock_flags & SFL_CLOSING))
|
||||||
|
|
||||||
|
#endif /* !_MINIX_SOCKEVENT_H */
|
@ -19,6 +19,7 @@ SUBDIR+= libminixfs
|
|||||||
SUBDIR+= libnetdriver
|
SUBDIR+= libnetdriver
|
||||||
SUBDIR+= libsffs
|
SUBDIR+= libsffs
|
||||||
SUBDIR+= libsockdriver
|
SUBDIR+= libsockdriver
|
||||||
|
SUBDIR+= libsockevent
|
||||||
SUBDIR+= libtimers
|
SUBDIR+= libtimers
|
||||||
SUBDIR+= libusb
|
SUBDIR+= libusb
|
||||||
SUBDIR+= libvtreefs
|
SUBDIR+= libvtreefs
|
||||||
|
9
minix/lib/libsockevent/Makefile
Normal file
9
minix/lib/libsockevent/Makefile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Makefile for libsockevent
|
||||||
|
|
||||||
|
CPPFLAGS+= -D_MINIX_SYSTEM -I${NETBSDSRCDIR}/minix/lib/libcharevent
|
||||||
|
|
||||||
|
LIB= sockevent
|
||||||
|
|
||||||
|
SRCS= sockevent.c sockevent_proc.c
|
||||||
|
|
||||||
|
.include <bsd.lib.mk>
|
2590
minix/lib/libsockevent/sockevent.c
Normal file
2590
minix/lib/libsockevent/sockevent.c
Normal file
File diff suppressed because it is too large
Load Diff
52
minix/lib/libsockevent/sockevent_proc.c
Normal file
52
minix/lib/libsockevent/sockevent_proc.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* libsockevent - sockevent_proc.c - process suspension state management */
|
||||||
|
|
||||||
|
#include <minix/drivers.h>
|
||||||
|
#include <minix/sockdriver.h>
|
||||||
|
|
||||||
|
#include "sockevent_proc.h"
|
||||||
|
|
||||||
|
static struct sockevent_proc sockevent_procs[NR_PROCS];
|
||||||
|
static struct sockevent_proc *sockevent_freeprocs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the process suspension table.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sockevent_proc_init(void)
|
||||||
|
{
|
||||||
|
unsigned int slot;
|
||||||
|
|
||||||
|
for (slot = 0; slot < __arraycount(sockevent_procs); slot++) {
|
||||||
|
sockevent_procs[slot].spr_next = sockevent_freeprocs;
|
||||||
|
sockevent_freeprocs = &sockevent_procs[slot];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate and return a new socket process suspension entry. Return NULL if
|
||||||
|
* no entries are available.
|
||||||
|
*/
|
||||||
|
struct sockevent_proc *
|
||||||
|
sockevent_proc_alloc(void)
|
||||||
|
{
|
||||||
|
struct sockevent_proc *spr;
|
||||||
|
|
||||||
|
if ((spr = sockevent_freeprocs) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sockevent_freeprocs = spr->spr_next;
|
||||||
|
spr->spr_next = NULL;
|
||||||
|
|
||||||
|
return spr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free up a previously allocated socket process suspension entry for reuse.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sockevent_proc_free(struct sockevent_proc * spr)
|
||||||
|
{
|
||||||
|
|
||||||
|
spr->spr_next = sockevent_freeprocs;
|
||||||
|
sockevent_freeprocs = spr;
|
||||||
|
}
|
25
minix/lib/libsockevent/sockevent_proc.h
Normal file
25
minix/lib/libsockevent/sockevent_proc.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef MINIX_SOCKEVENT_PROC_H
|
||||||
|
#define MINIX_SOCKEVENT_PROC_H
|
||||||
|
|
||||||
|
struct sockevent_proc {
|
||||||
|
struct sockevent_proc *spr_next; /* next on sock or free list */
|
||||||
|
unsigned char spr_event; /* event for call (SEV_) */
|
||||||
|
unsigned char spr_timer; /* suspended call has timer? */
|
||||||
|
struct sockdriver_call spr_call; /* call structure */
|
||||||
|
endpoint_t spr_endpt; /* user endpoint */
|
||||||
|
struct sockdriver_packed_data spr_data; /* regular data, packed */
|
||||||
|
size_t spr_datalen; /* length of regular data */
|
||||||
|
size_t spr_dataoff; /* offset into regular data */
|
||||||
|
struct sockdriver_packed_data spr_ctl; /* control data, packed */
|
||||||
|
socklen_t spr_ctllen; /* length of control data */
|
||||||
|
socklen_t spr_ctloff; /* offset into control data */
|
||||||
|
int spr_flags; /* send/recv flags (MSG_) */
|
||||||
|
int spr_rflags; /* recv result flags (MSG_) */
|
||||||
|
clock_t spr_time; /* timeout time for call */
|
||||||
|
};
|
||||||
|
|
||||||
|
void sockevent_proc_init(void);
|
||||||
|
struct sockevent_proc *sockevent_proc_alloc(void);
|
||||||
|
void sockevent_proc_free(struct sockevent_proc *);
|
||||||
|
|
||||||
|
#endif /* !MINIX_SOCKEVENT_PROC_H */
|
@ -238,6 +238,7 @@ LIB${_lib:tu}= ${DESTDIR}/usr/lib/lib${_lib:S/xx/++/:S/atf_c/atf-c/}.a
|
|||||||
netsock \
|
netsock \
|
||||||
sffs \
|
sffs \
|
||||||
sockdriver \
|
sockdriver \
|
||||||
|
sockevent \
|
||||||
sys \
|
sys \
|
||||||
timers \
|
timers \
|
||||||
usb \
|
usb \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user