some changes to mux handling in mod-sys.c
This commit is contained in:
parent
e2accffa0e
commit
292f2cc265
@ -40,64 +40,6 @@
|
||||
#define HAWK_EPOCH_MON_WIN (1)
|
||||
#define HAWK_EPOCH_DAY_WIN (1)
|
||||
|
||||
/* =========================================================================
|
||||
* DOUBLY LINKED LIST
|
||||
* ========================================================================= */
|
||||
#define HAWK_APPEND_TO_LIST(list, node) do { \
|
||||
(node)->next = HAWK_NULL; \
|
||||
(node)->prev = (list)->last; \
|
||||
if ((list)->first) (list)->last->next = (node); \
|
||||
else (list)->first = (node); \
|
||||
(list)->last = (node); \
|
||||
} while(0)
|
||||
|
||||
#define HAWK_PREPPEND_TO_LIST(list, node) do { \
|
||||
(node)->prev = HAWK_NULL; \
|
||||
(node)->next = (list)->first; \
|
||||
if ((list)->last) (list)->first->prev = (node); \
|
||||
else (list)->last = (node); \
|
||||
(list)->first = (node); \
|
||||
} while(0)
|
||||
|
||||
#define HAWK_DELETE_FROM_LIST(list, node) do { \
|
||||
if ((node)->prev) (node)->prev->next = (node)->next; \
|
||||
else (list)->first = (node)->next; \
|
||||
if ((node)->next) (node)->next->prev = (node)->prev; \
|
||||
else (list)->last = (node)->prev; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define HAWK_APPEND_TO_OOP_LIST(hawk, list, node_type, node, _link) do { \
|
||||
(node)->_link.next = (node_type)(hawk)->_nil; \
|
||||
(node)->_link.prev = (list)->last; \
|
||||
if ((hawk_oop_t)(list)->last != (hawk)->_nil) (list)->last->_link.next = (node); \
|
||||
else (list)->first = (node); \
|
||||
(list)->last = (node); \
|
||||
} while(0)
|
||||
|
||||
#define HAWK_PREPPEND_TO_OOP_LIST(hawk, list, node_type, node, _link) do { \
|
||||
(node)->_link.prev = (node_type)(hawk)->_nil; \
|
||||
(node)->_link.next = (list)->first; \
|
||||
if ((hawk_oop_t)(list)->first != (hawk)->_nil) (list)->first->_link.prev = (node); \
|
||||
else (list)->last = (node); \
|
||||
(list)->first = (node); \
|
||||
} while(0)
|
||||
|
||||
#define HAWK_DELETE_FROM_OOP_LIST(hawk, list, node, _link) do { \
|
||||
if ((hawk_oop_t)(node)->_link.prev != (hawk)->_nil) (node)->_link.prev->_link.next = (node)->_link.next; \
|
||||
else (list)->first = (node)->_link.next; \
|
||||
if ((hawk_oop_t)(node)->_link.next != (hawk)->_nil) (node)->_link.next->_link.prev = (node)->_link.prev; \
|
||||
else (list)->last = (node)->_link.prev; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
#define HAWK_CLEANUP_FROM_OOP_LIST(hawk, list, node, _link) do { \
|
||||
HAWK_DELETE_FROM_OOP_LIST (hawk, list, node, _link); \
|
||||
(node)->_link.prev = (node_type)(hawk)->_nil; \
|
||||
(node)->_link.next = (node_type)(hawk)->_nil; \
|
||||
} while(0);
|
||||
*/
|
||||
|
||||
/* =========================================================================
|
||||
* ENDIAN CHANGE OF A CONSTANT
|
||||
* ========================================================================= */
|
||||
|
@ -116,28 +116,45 @@ enum sys_node_data_flag_t
|
||||
};
|
||||
typedef enum sys_node_data_flag_t sys_node_data_flag_t;
|
||||
|
||||
struct sys_node_data_t
|
||||
{
|
||||
sys_node_data_type_t type;
|
||||
int flags;
|
||||
void* extra; /* if SYS_NODE_DATA_FLAG_IN_MUX is set, this is set to a valid pointer. it is of the void* type since sys_node_t is not available yet. */
|
||||
union
|
||||
{
|
||||
struct
|
||||
|
||||
struct sys_node_data_file_t
|
||||
{
|
||||
int fd;
|
||||
} file;
|
||||
struct
|
||||
void* mux; /* if SYS_NODE_DATA_FLAG_IN_MUX is set, this is set to a valid pointer. it is of the void* type since sys_node_t is not available yet. */
|
||||
void* x_prev;
|
||||
void* x_next;
|
||||
};
|
||||
typedef struct sys_node_data_file_t sys_node_data_file_t;
|
||||
|
||||
struct sys_node_data_sck_t
|
||||
{
|
||||
int fd;
|
||||
} sck;
|
||||
hawk_dir_t* dir;
|
||||
struct
|
||||
void* mux; /* if SYS_NODE_DATA_FLAG_IN_MUX is set, this is set to a valid pointer. it is of the void* type since sys_node_t is not available yet. */
|
||||
void* x_prev;
|
||||
void* x_next;
|
||||
};
|
||||
typedef struct sys_node_data_sck_t sys_node_data_sck_t;
|
||||
|
||||
struct sys_node_data_mux_t
|
||||
{
|
||||
#if defined(USE_EPOLL)
|
||||
int fd;
|
||||
#endif
|
||||
} mux;
|
||||
void* x_first;
|
||||
void* x_last;
|
||||
};
|
||||
typedef struct sys_node_data_mux_t sys_node_data_mux_t;
|
||||
|
||||
struct sys_node_data_t
|
||||
{
|
||||
sys_node_data_type_t type;
|
||||
int flags;
|
||||
union
|
||||
{
|
||||
sys_node_data_file_t file;
|
||||
sys_node_data_sck_t sck;
|
||||
hawk_dir_t* dir;
|
||||
sys_node_data_mux_t mux;
|
||||
} u;
|
||||
};
|
||||
typedef struct sys_node_data_t sys_node_data_t;
|
||||
@ -260,6 +277,39 @@ static sys_node_t* new_sys_node_mux (hawk_rtx_t* rtx, sys_list_t* list, int fd)
|
||||
return node;
|
||||
}
|
||||
|
||||
static void chain_sys_node_to_mux_node (sys_node_t* mux_node, sys_node_t* node)
|
||||
{
|
||||
sys_node_data_mux_t* mux_data = &mux_node->ctx.u.mux;
|
||||
sys_node_data_file_t* file_data = &node->ctx.u.file;
|
||||
|
||||
HAWK_ASSERT (!(node->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX));
|
||||
node->ctx.flags |= SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
|
||||
file_data->mux = mux_node;
|
||||
file_data->x_prev = HAWK_NULL;
|
||||
file_data->x_next = mux_data->x_first;
|
||||
if (mux_data->x_first) ((sys_node_t*)mux_data->x_first)->ctx.u.file.x_prev = node;
|
||||
else mux_data->x_last = node;
|
||||
mux_data->x_first = node;
|
||||
}
|
||||
|
||||
static void unchain_sys_node_from_mux_node (sys_node_t* mux_node, sys_node_t* node)
|
||||
{
|
||||
sys_node_data_mux_t* mux_data = &mux_node->ctx.u.mux;
|
||||
sys_node_data_file_t* file_data = &node->ctx.u.file;
|
||||
|
||||
HAWK_ASSERT (node->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX);
|
||||
node->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
|
||||
if (file_data->x_prev) ((sys_node_t*)file_data->x_prev)->ctx.u.file.x_next = file_data->x_next;
|
||||
else mux_data->x_first = file_data->x_next;
|
||||
if (file_data->x_next) ((sys_node_t*)file_data->x_next)->ctx.u.file.x_prev = file_data->x_prev;
|
||||
else mux_data->x_last = file_data->x_prev;
|
||||
|
||||
file_data->mux = HAWK_NULL;
|
||||
}
|
||||
|
||||
|
||||
static void del_from_mux (hawk_rtx_t* rtx, sys_node_t* fd_node)
|
||||
{
|
||||
if (fd_node->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX)
|
||||
@ -269,35 +319,37 @@ static void del_from_mux (hawk_rtx_t* rtx, sys_node_t* fd_node)
|
||||
struct epoll_event ev;
|
||||
#endif
|
||||
|
||||
mux_node = (sys_node_t*)fd_node->ctx.extra;
|
||||
switch (fd_node->ctx.type)
|
||||
{
|
||||
case SYS_NODE_DATA_TYPE_FILE:
|
||||
mux_node = (sys_node_t*)fd_node->ctx.u.file.mux;
|
||||
#if defined(USE_EPOLL)
|
||||
epoll_ctl (mux_node->ctx.u.mux.fd, EPOLL_CTL_DEL, fd_node->ctx.u.file.fd, &ev);
|
||||
#endif
|
||||
unchain_sys_node_from_mux_node (mux_node, fd_node);
|
||||
break;
|
||||
|
||||
case SYS_NODE_DATA_TYPE_SCK:
|
||||
mux_node = (sys_node_t*)fd_node->ctx.u.sck.mux;
|
||||
#if defined(USE_EPOLL)
|
||||
epoll_ctl (mux_node->ctx.u.mux.fd, EPOLL_CTL_DEL, fd_node->ctx.u.sck.fd, &ev);
|
||||
#endif
|
||||
unchain_sys_node_from_mux_node (mux_node, fd_node);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing */
|
||||
fd_node->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
break;
|
||||
}
|
||||
|
||||
fd_node->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
fd_node->ctx.extra = HAWK_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void purge_mux_members (hawk_rtx_t* rtx, sys_node_t* mux_node)
|
||||
{
|
||||
while (mux_node->ctx.extra)
|
||||
while (mux_node->ctx.u.mux.x_first)
|
||||
{
|
||||
del_from_mux (rtx, mux_node->ctx.extra);
|
||||
del_from_mux (rtx, mux_node->ctx.u.mux.x_first);
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,7 +759,8 @@ static int fnc_dup (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
|
||||
}
|
||||
#endif
|
||||
sys_node2->ctx.u.file.fd = fd; /* dup2 or dup3 closes the descriptor implicitly */
|
||||
/* dup2 or dup3 closes the descriptor sys_node2_.ctx.u.file.fd implicitly */
|
||||
sys_node2->ctx.u.file.fd = fd;
|
||||
rx = sys_node2->id;
|
||||
}
|
||||
else
|
||||
@ -2840,15 +2893,33 @@ static HAWK_INLINE int ctl_epoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, in
|
||||
|
||||
ev.events = events;
|
||||
ev.data.ptr = sys_node2;
|
||||
|
||||
|
||||
if (sys_node2->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX)
|
||||
{
|
||||
/* in actual operating systems, a file descriptor can
|
||||
* be watched under multiple I/O multiplexers. but this
|
||||
* implementation only allows 1 multiplexer for each
|
||||
* file descriptor for simplicity */
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EPERM, HAWK_T("already in mux"));
|
||||
goto done;
|
||||
}
|
||||
/* TODO: cmd == MOD, check if sys_node is equal to sys_node2->ctx.u.file.mux??? */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(sys_node2->ctx.flags & SYS_NODE_DATA_FLAG_IN_MUX))
|
||||
{
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EPERM, HAWK_T("not in mux"));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
switch (sys_node2->ctx.type)
|
||||
{
|
||||
case SYS_NODE_DATA_TYPE_FILE:
|
||||
evfd = sys_node2->ctx.u.file.fd;
|
||||
break;
|
||||
case SYS_NODE_DATA_TYPE_SCK:
|
||||
evfd = sys_node2->ctx.u.sck.fd;
|
||||
evfd = sys_node2->ctx.u.file.fd;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2863,16 +2934,26 @@ static HAWK_INLINE int ctl_epoll (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi, in
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (sys_node2->ctx.type)
|
||||
{
|
||||
case SYS_NODE_DATA_TYPE_FILE:
|
||||
case SYS_NODE_DATA_TYPE_SCK:
|
||||
if (cmd != EPOLL_CTL_DEL)
|
||||
{
|
||||
sys_node2->ctx.flags |= SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
sys_node2->ctx.extra = sys_node;
|
||||
chain_sys_node_to_mux_node (sys_node, sys_node2);
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_node2->ctx.flags &= ~SYS_NODE_DATA_FLAG_IN_MUX;
|
||||
sys_node2->ctx.extra = HAWK_NULL;
|
||||
unchain_sys_node_from_mux_node(sys_node, sys_node2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* internal error */
|
||||
rx = set_error_on_sys_list(rtx, sys_list, HAWK_EINTERN, HAWK_NULL);
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user