improved error handling in mio_dev_make()
This commit is contained in:
parent
07e6a1ac70
commit
f7c441b981
@ -312,6 +312,7 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, mio_dev_sck_bind_t* sck_bind, mi
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
info.m.options = MIO_DEV_SCK_MAKE_LENIENT;
|
||||||
info.m.on_write = listener_on_write;
|
info.m.on_write = listener_on_write;
|
||||||
info.m.on_read = listener_on_read;
|
info.m.on_read = listener_on_read;
|
||||||
info.m.on_connect = listener_on_connect;
|
info.m.on_connect = listener_on_connect;
|
||||||
@ -332,7 +333,6 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, mio_dev_sck_bind_t* sck_bind, mi
|
|||||||
if (mio_dev_sck_bind(htts->lsck, sck_bind) <= -1) goto oops;
|
if (mio_dev_sck_bind(htts->lsck, sck_bind) <= -1) goto oops;
|
||||||
|
|
||||||
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
||||||
info.l.options = MIO_DEV_SCK_LISTEN_LENIENT;
|
|
||||||
info.l.backlogs = 4096;
|
info.l.backlogs = 4096;
|
||||||
MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1);
|
MIO_INIT_NTIME (&info.l.accept_tmout, 5, 1);
|
||||||
if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
|
if (mio_dev_sck_listen(htts->lsck, &info.l) <= -1) goto oops;
|
||||||
|
@ -324,6 +324,7 @@ static mio_dev_mth_t dev_mar_methods =
|
|||||||
{
|
{
|
||||||
dev_mar_make,
|
dev_mar_make,
|
||||||
dev_mar_kill,
|
dev_mar_kill,
|
||||||
|
MIO_NULL,
|
||||||
dev_mar_getsyshnd,
|
dev_mar_getsyshnd,
|
||||||
|
|
||||||
MIO_NULL,
|
MIO_NULL,
|
||||||
|
@ -287,7 +287,10 @@ typedef enum mio_dev_sck_type_t mio_dev_sck_type_t;
|
|||||||
enum mio_dev_sck_make_option_t
|
enum mio_dev_sck_make_option_t
|
||||||
{
|
{
|
||||||
/* import the system handle specified in the hnd field */
|
/* import the system handle specified in the hnd field */
|
||||||
MIO_DEV_SCK_MAKE_IMPSYSHND = (1 << 0)
|
MIO_DEV_SCK_MAKE_IMPSYSHND = (1 << 0),
|
||||||
|
|
||||||
|
/* for now, accept failure doesn't affect the listing socket if this is set */
|
||||||
|
MIO_DEV_SCK_MAKE_LENIENT = (1 << 1)
|
||||||
};
|
};
|
||||||
typedef enum mio_dev_sck_make_option_t mio_dev_sck_make_option_t;
|
typedef enum mio_dev_sck_make_option_t mio_dev_sck_make_option_t;
|
||||||
|
|
||||||
@ -346,16 +349,17 @@ struct mio_dev_sck_connect_t
|
|||||||
mio_ntime_t connect_tmout;
|
mio_ntime_t connect_tmout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
enum mio_dev_sck_listen_option_t
|
enum mio_dev_sck_listen_option_t
|
||||||
{
|
{
|
||||||
MIO_DEV_SCK_LISTEN_LENIENT = (1 << 0) /* for now, accept failure doesn't affect the listing socket if this is set */
|
|
||||||
};
|
};
|
||||||
typedef enum mio_dev_sck_listen_option_t mio_dev_sck_listen_option_t;
|
typedef enum mio_dev_sck_listen_option_t mio_dev_sck_listen_option_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct mio_dev_sck_listen_t mio_dev_sck_listen_t;
|
typedef struct mio_dev_sck_listen_t mio_dev_sck_listen_t;
|
||||||
struct mio_dev_sck_listen_t
|
struct mio_dev_sck_listen_t
|
||||||
{
|
{
|
||||||
int options;
|
int options; /* no options as of now. set it to 0 */
|
||||||
int backlogs;
|
int backlogs;
|
||||||
mio_ntime_t accept_tmout;
|
mio_ntime_t accept_tmout;
|
||||||
};
|
};
|
||||||
|
@ -809,16 +809,21 @@ int mio_loop (mio_t* mio)
|
|||||||
|
|
||||||
mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth, mio_dev_evcb_t* dev_evcb, void* make_ctx)
|
mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth, mio_dev_evcb_t* dev_evcb, void* make_ctx)
|
||||||
{
|
{
|
||||||
mio_dev_t* dev;
|
mio_dev_t* dev = MIO_NULL;
|
||||||
|
|
||||||
if (dev_size < MIO_SIZEOF(mio_dev_t))
|
if (dev_size < MIO_SIZEOF(mio_dev_t))
|
||||||
{
|
{
|
||||||
mio_seterrnum (mio, MIO_EINVAL);
|
mio_seterrnum (mio, MIO_EINVAL);
|
||||||
return MIO_NULL;
|
if (dev_mth->fail_before_make) dev_mth->fail_before_make (make_ctx);
|
||||||
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = (mio_dev_t*)mio_callocmem(mio, dev_size);
|
dev = (mio_dev_t*)mio_callocmem(mio, dev_size);
|
||||||
if (MIO_UNLIKELY(!dev)) return MIO_NULL;
|
if (MIO_UNLIKELY(!dev))
|
||||||
|
{
|
||||||
|
if (dev_mth->fail_before_make) dev_mth->fail_before_make (make_ctx);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
dev->mio = mio;
|
dev->mio = mio;
|
||||||
dev->dev_size = dev_size;
|
dev->dev_size = dev_size;
|
||||||
@ -833,12 +838,7 @@ mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
|
|||||||
dev->cw_count = 0;
|
dev->cw_count = 0;
|
||||||
|
|
||||||
/* call the callback function first */
|
/* call the callback function first */
|
||||||
mio_seterrnum (mio, MIO_ENOERR);
|
if (dev->dev_mth->make(dev, make_ctx) <= -1) goto oops;
|
||||||
if (dev->dev_mth->make(dev, make_ctx) <= -1)
|
|
||||||
{
|
|
||||||
if (mio->errnum == MIO_ENOERR) mio_seterrnum (mio, MIO_EDEVMAKE);
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the make callback must not change these fields */
|
/* the make callback must not change these fields */
|
||||||
MIO_ASSERT (mio, dev->dev_mth == dev_mth);
|
MIO_ASSERT (mio, dev->dev_mth == dev_mth);
|
||||||
@ -883,13 +883,12 @@ oops_after_make:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MIO_NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MIO_NULL;
|
return MIO_NULL;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
mio_freemem (mio, dev);
|
if (dev) mio_freemem (mio, dev);
|
||||||
return MIO_NULL;
|
return MIO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,10 +182,12 @@ struct mio_dev_mth_t
|
|||||||
*/
|
*/
|
||||||
int (*kill) (mio_dev_t* dev, int force);
|
int (*kill) (mio_dev_t* dev, int force);
|
||||||
|
|
||||||
|
/* optional. called if mio_dev_make() fails before the make() method is called */
|
||||||
|
void (*fail_before_make) (void* ctx);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
mio_syshnd_t (*getsyshnd) (mio_dev_t* dev); /* mandatory. called in mio_dev_make() after successful make() */
|
mio_syshnd_t (*getsyshnd) (mio_dev_t* dev); /* mandatory. called in mio_dev_make() after successful make() */
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
|
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
|
||||||
* when returning 1, *len must be sent to the length of data read.
|
* when returning 1, *len must be sent to the length of data read.
|
||||||
|
@ -350,6 +350,7 @@ static mio_dev_mth_t dev_pipe_methods =
|
|||||||
{
|
{
|
||||||
dev_pipe_make_master,
|
dev_pipe_make_master,
|
||||||
dev_pipe_kill_master,
|
dev_pipe_kill_master,
|
||||||
|
MIO_NULL,
|
||||||
dev_pipe_getsyshnd,
|
dev_pipe_getsyshnd,
|
||||||
|
|
||||||
MIO_NULL,
|
MIO_NULL,
|
||||||
@ -362,6 +363,7 @@ static mio_dev_mth_t dev_pipe_methods_slave =
|
|||||||
{
|
{
|
||||||
dev_pipe_make_slave,
|
dev_pipe_make_slave,
|
||||||
dev_pipe_kill_slave,
|
dev_pipe_kill_slave,
|
||||||
|
MIO_NULL,
|
||||||
dev_pipe_getsyshnd_slave,
|
dev_pipe_getsyshnd_slave,
|
||||||
|
|
||||||
dev_pipe_read_slave,
|
dev_pipe_read_slave,
|
||||||
|
@ -730,6 +730,7 @@ static mio_dev_mth_t dev_pro_methods =
|
|||||||
{
|
{
|
||||||
dev_pro_make_master,
|
dev_pro_make_master,
|
||||||
dev_pro_kill_master,
|
dev_pro_kill_master,
|
||||||
|
MIO_NULL,
|
||||||
dev_pro_getsyshnd,
|
dev_pro_getsyshnd,
|
||||||
|
|
||||||
MIO_NULL, /* read */
|
MIO_NULL, /* read */
|
||||||
@ -743,6 +744,7 @@ static mio_dev_mth_t dev_pro_methods_slave =
|
|||||||
{
|
{
|
||||||
dev_pro_make_slave,
|
dev_pro_make_slave,
|
||||||
dev_pro_kill_slave,
|
dev_pro_kill_slave,
|
||||||
|
MIO_NULL,
|
||||||
dev_pro_getsyshnd_slave,
|
dev_pro_getsyshnd_slave,
|
||||||
|
|
||||||
dev_pro_read_slave,
|
dev_pro_read_slave,
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h> /* strerror */
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -79,7 +80,7 @@
|
|||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static void close_async_socket (mio_t* mio, mio_syshnd_t sck)
|
static MIO_INLINE void close_async_socket (mio_t* mio, mio_syshnd_t sck)
|
||||||
{
|
{
|
||||||
close (sck);
|
close (sck);
|
||||||
}
|
}
|
||||||
@ -399,6 +400,8 @@ static int dev_sck_make (mio_dev_t* dev, void* ctx)
|
|||||||
rdev->on_raw_accept = arg->on_raw_accept;
|
rdev->on_raw_accept = arg->on_raw_accept;
|
||||||
rdev->type = arg->type;
|
rdev->type = arg->type;
|
||||||
|
|
||||||
|
if (arg->options & MIO_DEV_SCK_MAKE_LENIENT) rdev->state |= MIO_DEV_SCK_LENIENT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
@ -423,12 +426,24 @@ static int dev_sck_make_client (mio_dev_t* dev, void* ctx)
|
|||||||
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
|
rdev->tmrjob_index = MIO_TMRIDX_INVALID;
|
||||||
rdev->side_chan = MIO_SYSHND_INVALID;
|
rdev->side_chan = MIO_SYSHND_INVALID;
|
||||||
|
|
||||||
/*if (mio_makesyshndasync(mio, rdev->hnd) <= -1 ||
|
if (mio_makesyshndasync(mio, rdev->hnd) <= -1 ||
|
||||||
mio_makesyshndcloexec(mio, rdev->hnd) <= -1) { printf ("cannot make sysnhnd async or cloexec %d\n", rdev->hnd); return -1; }
|
mio_makesyshndcloexec(mio, rdev->hnd) <= -1) goto oops;
|
||||||
*/
|
|
||||||
mio_makesyshndasync(mio, rdev->hnd);
|
|
||||||
mio_makesyshndcloexec(mio, rdev->hnd);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (rdev->hnd != MIO_SYSHND_INVALID)
|
||||||
|
{
|
||||||
|
close (rdev->hnd);
|
||||||
|
rdev->hnd = MIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dev_sck_fail_before_make_client (void* ctx)
|
||||||
|
{
|
||||||
|
mio_syshnd_t* clisckhnd = (mio_syshnd_t*)ctx;
|
||||||
|
close (*clisckhnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_sck_kill (mio_dev_t* dev, int force)
|
static int dev_sck_kill (mio_dev_t* dev, int force)
|
||||||
@ -1302,7 +1317,6 @@ fcntl (rdev->hnd, F_SETFL, flags | O_NONBLOCK);
|
|||||||
}
|
}
|
||||||
|
|
||||||
rdev->tmout = lstn->accept_tmout;
|
rdev->tmout = lstn->accept_tmout;
|
||||||
if (lstn->options & MIO_DEV_SCK_LISTEN_LENIENT) rdev->state |= MIO_DEV_SCK_LENIENT;
|
|
||||||
|
|
||||||
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_LISTENING);
|
MIO_DEV_SCK_SET_PROGRESS (rdev, MIO_DEV_SCK_LISTENING);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1316,6 +1330,7 @@ static mio_dev_mth_t dev_sck_methods_stateless =
|
|||||||
{
|
{
|
||||||
dev_sck_make,
|
dev_sck_make,
|
||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
|
MIO_NULL,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
|
||||||
dev_sck_read_stateless,
|
dev_sck_read_stateless,
|
||||||
@ -1330,6 +1345,7 @@ static mio_dev_mth_t dev_sck_methods_stateful =
|
|||||||
{
|
{
|
||||||
dev_sck_make,
|
dev_sck_make,
|
||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
|
MIO_NULL,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
|
||||||
dev_sck_read_stateful,
|
dev_sck_read_stateful,
|
||||||
@ -1343,6 +1359,7 @@ static mio_dev_mth_t dev_mth_clisck =
|
|||||||
{
|
{
|
||||||
dev_sck_make_client,
|
dev_sck_make_client,
|
||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
|
dev_sck_fail_before_make_client,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
|
||||||
dev_sck_read_stateful,
|
dev_sck_read_stateful,
|
||||||
@ -1469,8 +1486,8 @@ static int make_accepted_client_connection (mio_dev_sck_t* rdev, mio_syshnd_t cl
|
|||||||
clidev = (mio_dev_sck_t*)mio_dev_make(mio, rdev->dev_size, &dev_mth_clisck, rdev->dev_evcb, &clisck);
|
clidev = (mio_dev_sck_t*)mio_dev_make(mio, rdev->dev_size, &dev_mth_clisck, rdev->dev_evcb, &clisck);
|
||||||
if (MIO_UNLIKELY(!clidev))
|
if (MIO_UNLIKELY(!clidev))
|
||||||
{
|
{
|
||||||
|
/* [NOTE] 'clisck' is closed by callback methods called by mio_dev_make() upon failure */
|
||||||
MIO_DEBUG3 (mio, "SCK(%p) - unable to make a new accepted device for %d - %js\n", rdev, (int)clisck, mio_geterrmsg(mio));
|
MIO_DEBUG3 (mio, "SCK(%p) - unable to make a new accepted device for %d - %js\n", rdev, (int)clisck, mio_geterrmsg(mio));
|
||||||
close (clisck);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1925,9 +1942,8 @@ printf ("unable wrong packet size... \n");
|
|||||||
{
|
{
|
||||||
if (make_accepted_client_connection(rdev, qxmsg->syshnd, &qxmsg->remoteaddr, qxmsg->scktype) <= -1)
|
if (make_accepted_client_connection(rdev, qxmsg->syshnd, &qxmsg->remoteaddr, qxmsg->scktype) <= -1)
|
||||||
{
|
{
|
||||||
printf ("unable to accept new client connection\n");
|
printf ("unable to accept new client connection %d\n", qxmsg->syshnd);
|
||||||
close (qxmsg->syshnd);
|
return (rdev->state & MIO_DEV_SCK_LENIENT)? 0: -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -80,7 +80,7 @@ int mio_makesyshndasync (mio_t* mio, mio_syshnd_t hnd)
|
|||||||
if ((flags = fcntl(hnd, F_GETFL, 0)) <= -1 ||
|
if ((flags = fcntl(hnd, F_GETFL, 0)) <= -1 ||
|
||||||
fcntl(hnd, F_SETFL, flags | O_NONBLOCK) <= -1)
|
fcntl(hnd, F_SETFL, flags | O_NONBLOCK) <= -1)
|
||||||
{
|
{
|
||||||
printf ("make sysnhd async error (%d)\n", hnd);
|
printf ("make sysnhd async error (%d) - errno %d\n", hnd, errno);
|
||||||
mio_seterrwithsyserr (mio, 0, errno);
|
mio_seterrwithsyserr (mio, 0, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -100,7 +100,7 @@ int mio_makesyshndcloexec (mio_t* mio, mio_syshnd_t hnd)
|
|||||||
if ((flags = fcntl(hnd, F_GETFD, 0)) <= -1 ||
|
if ((flags = fcntl(hnd, F_GETFD, 0)) <= -1 ||
|
||||||
fcntl(hnd, F_SETFD, flags | FD_CLOEXEC) <= -1)
|
fcntl(hnd, F_SETFD, flags | FD_CLOEXEC) <= -1)
|
||||||
{
|
{
|
||||||
printf ("make sysnhd cloexec error (%d)\n", hnd);
|
printf ("make sysnhd cloexec error (%d) - errno %d\n", hnd, errno);
|
||||||
mio_seterrwithsyserr (mio, 0, errno);
|
mio_seterrwithsyserr (mio, 0, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -510,6 +510,7 @@ static mio_dev_mth_t dev_thr_methods =
|
|||||||
{
|
{
|
||||||
dev_thr_make_master,
|
dev_thr_make_master,
|
||||||
dev_thr_kill_master,
|
dev_thr_kill_master,
|
||||||
|
MIO_NULL,
|
||||||
dev_thr_getsyshnd,
|
dev_thr_getsyshnd,
|
||||||
|
|
||||||
MIO_NULL,
|
MIO_NULL,
|
||||||
@ -522,6 +523,7 @@ static mio_dev_mth_t dev_thr_methods_slave =
|
|||||||
{
|
{
|
||||||
dev_thr_make_slave,
|
dev_thr_make_slave,
|
||||||
dev_thr_kill_slave,
|
dev_thr_kill_slave,
|
||||||
|
MIO_NULL,
|
||||||
dev_thr_getsyshnd_slave,
|
dev_thr_getsyshnd_slave,
|
||||||
|
|
||||||
dev_thr_read_slave,
|
dev_thr_read_slave,
|
||||||
|
Loading…
Reference in New Issue
Block a user