#ifndef _SYS_PORT_IMPL_H
#define _SYS_PORT_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/poll_impl.h>
#include <sys/port.h>
#include <sys/port_kernel.h>
#include <sys/vnode.h>
#include <sys/fem.h>
#define PORT_CREATE 0
#define PORT_ASSOCIATE 1
#define PORT_DISSOCIATE 2
#define PORT_SEND 3
#define PORT_SENDN 4
#define PORT_GET 5
#define PORT_GETN 6
#define PORT_ALERT 7
#define PORT_DISPATCH 8
#define PORT_SYS_NOPORT 0x100
#define PORT_SYS_NOSHARE 0x200
#define PORT_CODE_MASK 0xff
#define PORT_SHARE_EVENT 0x01
#define PORT_MAX_LIST 8192
#ifdef _KERNEL
#define PORT_SCACHE_SIZE 16
#define PORT_SHASH(cookie) (cookie & (PORT_SCACHE_SIZE-1))
#define PORT_CLEANUP_DONE (PORT_KEV_FREE|PORT_KEV_DONEQ)
#define PORT_KEV_CACHE (PORT_KEV_CACHED|PORT_KEV_SCACHED)
#define PORT_KEV_WIRED (PORT_KEV_PRIVATE|PORT_KEV_CACHE)
#define PORT_FREE_EVENT(pev) (((pev)->portkev_flags & PORT_KEV_CACHE) == 0)
typedef struct port_alert {
int portal_events;
pid_t portal_pid;
uintptr_t portal_object;
void *portal_user;
} port_alert_t;
typedef struct port_queue {
kmutex_t portq_mutex;
kcondvar_t portq_closecv;
kcondvar_t portq_block_cv;
int portq_flags;
uint_t portq_nent;
uint_t portq_nget;
uint_t portq_tnent;
int portq_thrcnt;
int portq_getn;
struct portget *portq_thread;
struct port_fdcache *portq_pcp;
list_t portq_list;
list_t portq_get_list;
kmutex_t portq_source_mutex;
port_source_t **portq_scache;
port_alert_t portq_alert;
} port_queue_t;
#define PORTQ_ALERT 0x01
#define PORTQ_CLOSE 0x02
#define PORTQ_WAIT_EVENTS 0x04
#define PORTQ_POLLIN 0x08
#define PORTQ_POLLOUT 0x10
#define PORTQ_BLOCKED 0x20
#define PORTQ_POLLWK_PEND 0x40
#define VTOEP(v) ((struct port *)(v->v_data))
#define EPTOV(ep) ((struct vnode *)(ep)->port_vnode)
typedef struct port {
vnode_t *port_vnode;
kmutex_t port_mutex;
kcondvar_t port_cv;
uint_t port_flags;
pid_t port_pid;
int port_fd;
uint_t port_max_events;
uint_t port_max_list;
uint_t port_curr;
pollhead_t port_pollhd;
timespec_t port_ctime;
uid_t port_uid;
gid_t port_gid;
port_queue_t port_queue;
} port_t;
#define PORT_INIT 0x01
#define PORT_CLOSED 0x02
#define PORT_EVENTS 0x04
typedef struct port_control {
kmutex_t pc_mutex;
uint_t pc_nents;
struct kmem_cache *pc_cache;
} port_control_t;
typedef struct portget {
int portget_state;
uint_t portget_nget;
pid_t portget_pid;
kcondvar_t portget_cv;
port_alert_t portget_alert;
struct portget *portget_next;
struct portget *portget_prev;
} portget_t;
#define PORTGET_ALERT 0x01
extern port_control_t port_control;
extern uint_t port_max_list;
typedef struct port_gettimer {
ushort_t pgt_flags;
ushort_t pgt_loop;
int pgt_timecheck;
timespec_t pgt_rqtime;
timespec_t *pgt_rqtp;
struct timespec *pgt_timeout;
} port_gettimer_t;
#define PORTGET_ONE 0x01
#define PORTGET_WAIT_EVENTS 0x02
typedef struct portfd {
struct polldat pfd_pd;
struct portfd *pfd_next;
struct portfd *pfd_prev;
kthread_t *pfd_thread;
} portfd_t;
#define PFTOD(pfd) (&(pfd)->pfd_pd)
#define PDTOF(pdp) ((struct portfd *)(pdp))
#define PORT_FD_BUCKET(pcp, fd) \
(&(pcp)->pc_hash[((fd) % (pcp)->pc_hashsize)])
#define PORT_FOP_BUCKET(pcp, id) \
(portfop_t **)(&(pcp)->pfc_hash[(((ulong_t)id >> 8) & \
(PORTFOP_HASHSIZE - 1))])
typedef struct portfop {
int pfop_events;
int pfop_flags;
uintptr_t pfop_object;
vnode_t *pfop_vp;
vnode_t *pfop_dvp;
port_t *pfop_pp;
fem_t *pfop_fem;
list_node_t pfop_node;
struct portfop *pfop_hashnext;
pid_t pfop_pid;
struct portfop_cache *pfop_pcache;
port_kevent_t *pfop_pev;
char *pfop_cname;
int pfop_clen;
kthread_t *pfop_callrid;
} portfop_t;
#define PORT_FOP_ACTIVE 0x1
#define PORT_FOP_REMOVING 0x2
#define PORT_FOP_KEV_ONQ 0x4
typedef struct portfop_vfs {
vfs_t *pvfs;
int pvfs_unmount;
list_t pvfs_pvplist;
fsem_t *pvfs_fsemp;
struct portfop_vfs *pvfs_next;
} portfop_vfs_t;
typedef struct portfop_vfs_hash {
kmutex_t pvfshash_mutex;
struct portfop_vfs *pvfshash_pvfsp;
} portfop_vfs_hash_t;
typedef struct portfop_vp {
vnode_t *pvp_vp;
kmutex_t pvp_mutex;
int pvp_cnt;
list_t pvp_pfoplist;
list_node_t pvp_pvfsnode;
struct portfop *pvp_lpfop;
fem_t *pvp_femp;
struct portfop_vfs *pvp_pvfsp;
} portfop_vp_t;
#define PORTFOP_PVFSHASH_SZ 256
#define PORTFOP_PVFSHASH(vfsp) (((uintptr_t)(vfsp) >> 4) % PORTFOP_PVFSHASH_SZ)
#define FOP_FILE_OPEN 0x00000001
#define FOP_FILE_READ 0x00000002
#define FOP_FILE_WRITE 0x00000004
#define FOP_FILE_MAP 0x00000008
#define FOP_FILE_IOCTL 0x00000010
#define FOP_FILE_CREATE 0x00000020
#define FOP_FILE_MKDIR 0x00000040
#define FOP_FILE_SYMLINK 0x00000080
#define FOP_FILE_LINK 0x00000100
#define FOP_FILE_RENAME 0x00000200
#define FOP_FILE_REMOVE 0x00000400
#define FOP_FILE_RMDIR 0x00000800
#define FOP_FILE_READDIR 0x00001000
#define FOP_FILE_RENAMESRC 0x00002000
#define FOP_FILE_RENAMEDST 0x00004000
#define FOP_FILE_REMOVEFILE 0x00008000
#define FOP_FILE_REMOVEDIR 0x00010000
#define FOP_FILE_SETSECATTR 0x00020000
#define FOP_FILE_SETATTR_ATIME 0x00040000
#define FOP_FILE_SETATTR_MTIME 0x00080000
#define FOP_FILE_SETATTR_CTIME 0x00100000
#define FOP_FILE_LINK_SRC 0x00200000
#define FOP_FILE_TRUNC 0x00400000
#define FOP_MODIFIED_MASK (FOP_FILE_WRITE|FOP_FILE_CREATE \
|FOP_FILE_REMOVE|FOP_FILE_LINK \
|FOP_FILE_RENAMESRC|FOP_FILE_RENAMEDST \
|FOP_FILE_MKDIR|FOP_FILE_RMDIR \
|FOP_FILE_SYMLINK|FOP_FILE_SETATTR_MTIME)
#define FOP_ACCESS_MASK (FOP_FILE_READ|FOP_FILE_READDIR \
|FOP_FILE_MAP|FOP_FILE_SETATTR_ATIME)
#define FOP_ATTRIB_MASK (FOP_FILE_WRITE|FOP_FILE_CREATE \
|FOP_FILE_REMOVE|FOP_FILE_LINK \
|FOP_FILE_RENAMESRC|FOP_FILE_RENAMEDST \
|FOP_FILE_MKDIR|FOP_FILE_RMDIR \
|FOP_FILE_SYMLINK|FOP_FILE_SETATTR_CTIME \
|FOP_FILE_LINK_SRC|FOP_FILE_SETSECATTR)
#define FOP_TRUNC_MASK (FOP_FILE_TRUNC|FOP_FILE_CREATE)
#define FILE_EVENTS_MASK (FILE_ACCESS|FILE_MODIFIED|FILE_ATTRIB \
|FILE_NOFOLLOW|FILE_TRUNC)
typedef struct port_kstat {
kstat_named_t pks_ports;
} port_kstat_t;
int port_alloc_event_block(port_t *, int, int, struct port_kevent **);
void port_push_eventq(port_queue_t *);
int port_remove_done_event(struct port_kevent *);
struct port_kevent *port_get_kevent(list_t *, struct port_kevent *);
void port_block(port_queue_t *);
void port_unblock(port_queue_t *);
void port_pcache_remove_fd(port_fdcache_t *, portfd_t *);
int port_remove_fd_object(portfd_t *, struct port *, port_fdcache_t *);
extern void addfd_port(int, portfd_t *);
extern void delfd_port(int, portfd_t *);
#endif
#ifdef __cplusplus
}
#endif
#endif