added the default group option to the mariadb device and the mariadb client service
added the issyshndbroken() callback to hio_dev_mth_t implemented the callback in the mariadb device. enhanced the epoll/kqueue multiplexer implementation to use the callback
This commit is contained in:
parent
9558e12c3e
commit
d7e5ebdf4f
@ -237,7 +237,7 @@ int main (int argc, char* argv[])
|
|||||||
HIO_INIT_NTIME (&tmout.w, -1, 0);
|
HIO_INIT_NTIME (&tmout.w, -1, 0);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
marc = hio_svc_marc_start(hio, &ci, HIO_NULL);
|
marc = hio_svc_marc_start(hio, &ci, HIO_NULL, HIO_NULL);
|
||||||
if (!marc)
|
if (!marc)
|
||||||
{
|
{
|
||||||
printf ("Cannot start a mariadb client service\n");
|
printf ("Cannot start a mariadb client service\n");
|
||||||
|
@ -125,6 +125,8 @@ struct hio_dev_mar_make_t
|
|||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
hio_dev_mar_tmout_t tmout;
|
hio_dev_mar_tmout_t tmout;
|
||||||
|
const hio_bch_t* default_group;
|
||||||
|
|
||||||
hio_dev_mar_on_write_t on_write; /* mandatory */
|
hio_dev_mar_on_write_t on_write; /* mandatory */
|
||||||
hio_dev_mar_on_read_t on_read; /* mandatory */
|
hio_dev_mar_on_read_t on_read; /* mandatory */
|
||||||
hio_dev_mar_on_connect_t on_connect; /* optional */
|
hio_dev_mar_on_connect_t on_connect; /* optional */
|
||||||
@ -251,7 +253,8 @@ HIO_EXPORT hio_oow_t hio_dev_mar_escapebchars (
|
|||||||
HIO_EXPORT hio_svc_marc_t* hio_svc_marc_start (
|
HIO_EXPORT hio_svc_marc_t* hio_svc_marc_start (
|
||||||
hio_t* hio,
|
hio_t* hio,
|
||||||
const hio_svc_marc_connect_t* ci,
|
const hio_svc_marc_connect_t* ci,
|
||||||
const hio_svc_marc_tmout_t* tmout
|
const hio_svc_marc_tmout_t* tmout,
|
||||||
|
const hio_bch_t* default_group
|
||||||
);
|
);
|
||||||
|
|
||||||
HIO_EXPORT void hio_svc_marc_stop (
|
HIO_EXPORT void hio_svc_marc_stop (
|
||||||
|
@ -222,7 +222,8 @@ struct hio_dev_mth_t
|
|||||||
void (*fail_before_make) (void* ctx);
|
void (*fail_before_make) (void* ctx);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
hio_syshnd_t (*getsyshnd) (hio_dev_t* dev); /* mandatory. called in hio_dev_make() after successful make() */
|
hio_syshnd_t (*getsyshnd) (hio_dev_t* dev); /* mandatory. called in hio_dev_make() after successful make() */
|
||||||
|
int (*issyshndbroken) (hio_dev_t* dev); /* the device whose underlying system handle can get closed before kill() must implement this */
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
|
/* return -1 on failure, 0 if no data is availble, 1 otherwise.
|
||||||
|
@ -45,6 +45,8 @@ struct hio_svc_marc_t
|
|||||||
int stopping;
|
int stopping;
|
||||||
int tmout_set;
|
int tmout_set;
|
||||||
|
|
||||||
|
const hio_bch_t* default_group;
|
||||||
|
|
||||||
hio_svc_marc_connect_t ci;
|
hio_svc_marc_connect_t ci;
|
||||||
hio_svc_marc_tmout_t tmout;
|
hio_svc_marc_tmout_t tmout;
|
||||||
|
|
||||||
@ -90,7 +92,7 @@ struct dev_xtn_t
|
|||||||
|
|
||||||
#define INVALID_SID HIO_TYPE_MAX(hio_oow_t)
|
#define INVALID_SID HIO_TYPE_MAX(hio_oow_t)
|
||||||
|
|
||||||
hio_svc_marc_t* hio_svc_marc_start (hio_t* hio, const hio_svc_marc_connect_t* ci, const hio_svc_marc_tmout_t* tmout)
|
hio_svc_marc_t* hio_svc_marc_start (hio_t* hio, const hio_svc_marc_connect_t* ci, const hio_svc_marc_tmout_t* tmout, const hio_bch_t* default_group)
|
||||||
{
|
{
|
||||||
hio_svc_marc_t* marc = HIO_NULL;
|
hio_svc_marc_t* marc = HIO_NULL;
|
||||||
|
|
||||||
@ -108,6 +110,7 @@ hio_svc_marc_t* hio_svc_marc_start (hio_t* hio, const hio_svc_marc_connect_t* ci
|
|||||||
marc->tmout = *tmout;
|
marc->tmout = *tmout;
|
||||||
marc->tmout_set = 1;
|
marc->tmout_set = 1;
|
||||||
}
|
}
|
||||||
|
marc->default_group = default_group;
|
||||||
|
|
||||||
HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)marc);
|
HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)marc);
|
||||||
return marc;
|
return marc;
|
||||||
@ -368,6 +371,7 @@ static hio_dev_mar_t* alloc_device (hio_svc_marc_t* marc, hio_oow_t sid)
|
|||||||
mi.flags = HIO_DEV_MAR_USE_TMOUT;
|
mi.flags = HIO_DEV_MAR_USE_TMOUT;
|
||||||
mi.tmout = marc->tmout;
|
mi.tmout = marc->tmout;
|
||||||
}
|
}
|
||||||
|
mi.default_group = marc->default_group;
|
||||||
|
|
||||||
mi.on_connect = mar_on_connect;
|
mi.on_connect = mar_on_connect;
|
||||||
mi.on_disconnect = mar_on_disconnect;
|
mi.on_disconnect = mar_on_disconnect;
|
||||||
@ -378,11 +382,12 @@ static hio_dev_mar_t* alloc_device (hio_svc_marc_t* marc, hio_oow_t sid)
|
|||||||
if (HIO_UNLIKELY(!mar)) return HIO_NULL;
|
if (HIO_UNLIKELY(!mar)) return HIO_NULL;
|
||||||
|
|
||||||
xtn = (dev_xtn_t*)hio_dev_mar_getxtn(mar);
|
xtn = (dev_xtn_t*)hio_dev_mar_getxtn(mar);
|
||||||
xtn->sid = sid;
|
|
||||||
xtn->svc = marc;
|
xtn->svc = marc;
|
||||||
|
xtn->sid = sid;
|
||||||
|
|
||||||
if (hio_dev_mar_connect(mar, &marc->ci) <= -1)
|
if (hio_dev_mar_connect(mar, &marc->ci) <= -1)
|
||||||
{
|
{
|
||||||
|
/* connection failed immediately */
|
||||||
xtn->sid = INVALID_SID;
|
xtn->sid = INVALID_SID;
|
||||||
hio_dev_mar_halt (mar);
|
hio_dev_mar_halt (mar);
|
||||||
return HIO_NULL;
|
return HIO_NULL;
|
||||||
@ -422,8 +427,8 @@ static sess_t* get_session (hio_svc_marc_t* marc, hio_oow_t sid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sess = &marc->sess.ptr[sid];
|
sess = &marc->sess.ptr[sid];
|
||||||
HIO_ASSERT (hio, sess->sid == sid);
|
|
||||||
HIO_ASSERT (hio, sess->svc == marc);
|
HIO_ASSERT (hio, sess->svc == marc);
|
||||||
|
HIO_ASSERT (hio, sess->sid == sid);
|
||||||
|
|
||||||
if (!sess->dev)
|
if (!sess->dev)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,9 @@ static int dev_mar_make (hio_dev_t* dev, void* ctx)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mi->default_group) /* don't care about success/failure */
|
||||||
|
mysql_options(rdev->hnd, MYSQL_READ_DEFAULT_GROUP, mi->default_group);
|
||||||
|
|
||||||
if (mysql_options(rdev->hnd, MYSQL_OPT_NONBLOCK, 0) != 0)
|
if (mysql_options(rdev->hnd, MYSQL_OPT_NONBLOCK, 0) != 0)
|
||||||
{
|
{
|
||||||
hio_seterrbfmt (hio, HIO_ESYSERR, "%hs", mysql_error(rdev->hnd));
|
hio_seterrbfmt (hio, HIO_ESYSERR, "%hs", mysql_error(rdev->hnd));
|
||||||
@ -137,6 +140,7 @@ static int dev_mar_kill (hio_dev_t* dev, int force)
|
|||||||
|
|
||||||
rdev->connected = 0;
|
rdev->connected = 0;
|
||||||
rdev->broken = 0;
|
rdev->broken = 0;
|
||||||
|
rdev->broken_syshnd = HIO_SYSHND_INVALID;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -148,6 +152,12 @@ static hio_syshnd_t dev_mar_getsyshnd (hio_dev_t* dev)
|
|||||||
return (hio_syshnd_t)mysql_get_socket(rdev->hnd);
|
return (hio_syshnd_t)mysql_get_socket(rdev->hnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dev_mar_issyshndbroken (hio_dev_t* dev)
|
||||||
|
{
|
||||||
|
hio_dev_mar_t* rdev = (hio_dev_mar_t*)dev;
|
||||||
|
return rdev->broken;
|
||||||
|
}
|
||||||
|
|
||||||
static int events_to_mysql_wstatus (int events)
|
static int events_to_mysql_wstatus (int events)
|
||||||
{
|
{
|
||||||
int wstatus = 0;
|
int wstatus = 0;
|
||||||
@ -235,12 +245,17 @@ static int dev_mar_ioctl (hio_dev_t* dev, int cmd, void* arg)
|
|||||||
if (HIO_UNLIKELY(!tmp)) /* connection attempt failed immediately */
|
if (HIO_UNLIKELY(!tmp)) /* connection attempt failed immediately */
|
||||||
{
|
{
|
||||||
/* immediate failure doesn't invoke on_discoonect().
|
/* immediate failure doesn't invoke on_discoonect().
|
||||||
* the caller must check the return code of this function. */
|
* the caller must check the return code of this function. */
|
||||||
|
|
||||||
|
rdev->connected = 0;
|
||||||
|
rdev->broken = 1;
|
||||||
|
rdev->broken_syshnd = HIO_SYSHND_INVALID;
|
||||||
|
|
||||||
hio_seterrbfmt (hio, HIO_ESYSERR, "%hs", mysql_error(rdev->hnd));
|
hio_seterrbfmt (hio, HIO_ESYSERR, "%hs", mysql_error(rdev->hnd));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connected_deferred immediately. postpone actual handling to the ready() callback */
|
/* connected immediately. postpone actual handling to the ready() callback */
|
||||||
HIO_DEV_MAR_SET_PROGRESS (rdev, HIO_DEV_MAR_CONNECTING);
|
HIO_DEV_MAR_SET_PROGRESS (rdev, HIO_DEV_MAR_CONNECTING);
|
||||||
rdev->connected_deferred = 1; /* to let the ready() handler to trigger on_connect() */
|
rdev->connected_deferred = 1; /* to let the ready() handler to trigger on_connect() */
|
||||||
/* regiter it in the multiplexer so that the ready() handler is
|
/* regiter it in the multiplexer so that the ready() handler is
|
||||||
@ -291,8 +306,12 @@ static int dev_mar_ioctl (hio_dev_t* dev, int cmd, void* arg)
|
|||||||
/* the underlying socket must have gotten closed by mysql_real_query_start() */
|
/* the underlying socket must have gotten closed by mysql_real_query_start() */
|
||||||
const hio_ooch_t* prev_errmsg;
|
const hio_ooch_t* prev_errmsg;
|
||||||
prev_errmsg = hio_backuperrmsg(hio);
|
prev_errmsg = hio_backuperrmsg(hio);
|
||||||
|
|
||||||
|
rdev->connected = 0;
|
||||||
rdev->broken = 1;
|
rdev->broken = 1;
|
||||||
rdev->broken_syshnd = syshnd;
|
/* remember the previous handle - this may be needed by the poll/select based multiplexer */
|
||||||
|
rdev->broken_syshnd = syshnd;
|
||||||
|
|
||||||
watch_mysql (rdev, 0);
|
watch_mysql (rdev, 0);
|
||||||
hio_dev_mar_halt (rdev); /* i can't keep this device alive regardless of the caller's post-action */
|
hio_dev_mar_halt (rdev); /* i can't keep this device alive regardless of the caller's post-action */
|
||||||
hio_seterrbfmt (hio, HIO_ESYSERR, "%js", prev_errmsg);
|
hio_seterrbfmt (hio, HIO_ESYSERR, "%js", prev_errmsg);
|
||||||
@ -335,6 +354,7 @@ static hio_dev_mth_t dev_mar_methods =
|
|||||||
dev_mar_kill,
|
dev_mar_kill,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_mar_getsyshnd,
|
dev_mar_getsyshnd,
|
||||||
|
dev_mar_issyshndbroken,
|
||||||
|
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
@ -416,8 +436,16 @@ static int dev_evcb_mar_ready (hio_dev_t* dev, int events)
|
|||||||
{
|
{
|
||||||
/* connection attempt failed */
|
/* connection attempt failed */
|
||||||
|
|
||||||
|
/* the mysql client library closes the underlying socket handle
|
||||||
|
* whenever the connection attempt fails. this prevent hio from
|
||||||
|
* managing the the mysql connections properly. this also causes
|
||||||
|
* race condition if this library is used in multi-threaded programs. */
|
||||||
|
|
||||||
|
rdev->connected = 0;
|
||||||
rdev->broken = 1; /* trick dev_mar_getsyshnd() to return rdev->broken_syshnd. */
|
rdev->broken = 1; /* trick dev_mar_getsyshnd() to return rdev->broken_syshnd. */
|
||||||
rdev->broken_syshnd = syshnd; /* mysql_get_socket() over a failed mariadb handle ends up with segfault */
|
/* remember the previous handle - this may be needed by the poll/select based multiplexer
|
||||||
|
* mysql_get_socket() over a failed mariadb handle ends up with segfault */
|
||||||
|
rdev->broken_syshnd = syshnd;
|
||||||
|
|
||||||
/* this attempts to trigger the low-level multiplxer to delete 'syshnd' closed by mysql_real_connect_cont().
|
/* this attempts to trigger the low-level multiplxer to delete 'syshnd' closed by mysql_real_connect_cont().
|
||||||
* the underlying low-level operation may fail. but i don't care. the best is not to open
|
* the underlying low-level operation may fail. but i don't care. the best is not to open
|
||||||
|
@ -376,6 +376,7 @@ static hio_dev_mth_t dev_pipe_methods =
|
|||||||
dev_pipe_kill_master,
|
dev_pipe_kill_master,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_pipe_getsyshnd,
|
dev_pipe_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
@ -389,6 +390,7 @@ static hio_dev_mth_t dev_pipe_methods_slave =
|
|||||||
dev_pipe_kill_slave,
|
dev_pipe_kill_slave,
|
||||||
dev_pipe_fail_before_make_slave,
|
dev_pipe_fail_before_make_slave,
|
||||||
dev_pipe_getsyshnd_slave,
|
dev_pipe_getsyshnd_slave,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_pipe_read_slave,
|
dev_pipe_read_slave,
|
||||||
dev_pipe_write_slave,
|
dev_pipe_write_slave,
|
||||||
|
@ -738,6 +738,7 @@ static hio_dev_mth_t dev_pro_methods =
|
|||||||
dev_pro_kill_master,
|
dev_pro_kill_master,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_pro_getsyshnd,
|
dev_pro_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
HIO_NULL, /* read */
|
HIO_NULL, /* read */
|
||||||
HIO_NULL, /* write */
|
HIO_NULL, /* write */
|
||||||
@ -752,6 +753,7 @@ static hio_dev_mth_t dev_pro_methods_slave =
|
|||||||
dev_pro_kill_slave,
|
dev_pro_kill_slave,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_pro_getsyshnd_slave,
|
dev_pro_getsyshnd_slave,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_pro_read_slave,
|
dev_pro_read_slave,
|
||||||
dev_pro_write_slave,
|
dev_pro_write_slave,
|
||||||
|
@ -1398,6 +1398,7 @@ static hio_dev_mth_t dev_mth_sck_stateless =
|
|||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_sck_read_stateless,
|
dev_sck_read_stateless,
|
||||||
dev_sck_write_stateless,
|
dev_sck_write_stateless,
|
||||||
@ -1413,6 +1414,7 @@ static hio_dev_mth_t dev_mth_sck_stateful =
|
|||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_sck_read_stateful,
|
dev_sck_read_stateful,
|
||||||
dev_sck_write_stateful,
|
dev_sck_write_stateful,
|
||||||
@ -1427,6 +1429,7 @@ static hio_dev_mth_t dev_mth_clisck =
|
|||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
dev_sck_fail_before_make_client,
|
dev_sck_fail_before_make_client,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_sck_read_stateful,
|
dev_sck_read_stateful,
|
||||||
dev_sck_write_stateful,
|
dev_sck_write_stateful,
|
||||||
@ -1441,6 +1444,7 @@ static hio_dev_mth_t dev_mth_sck_bpf =
|
|||||||
dev_sck_kill,
|
dev_sck_kill,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_sck_getsyshnd,
|
dev_sck_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_sck_read_bpf,
|
dev_sck_read_bpf,
|
||||||
dev_sck_write_bpf,
|
dev_sck_write_bpf,
|
||||||
|
@ -419,6 +419,11 @@ int hio_sys_ctrlmux (hio_t* hio, hio_sys_mux_cmd_t cmd, hio_dev_t* dev, int dev_
|
|||||||
int x;
|
int x;
|
||||||
|
|
||||||
HIO_ASSERT (hio, hio == dev->hio);
|
HIO_ASSERT (hio, hio == dev->hio);
|
||||||
|
|
||||||
|
/* no operation over a broken(closed) handle to prevent multiplexer from failing.
|
||||||
|
* close of the handle leads to auto-deletion from the kqueue multiplexer.
|
||||||
|
* the closed handle must not be fed to the multiplexer */
|
||||||
|
if (dev->dev_mth->issyshndbroken && dev->dev_mth->issyshndbroken(dev)) return 0;
|
||||||
hnd = dev->dev_mth->getsyshnd(dev);
|
hnd = dev->dev_mth->getsyshnd(dev);
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -495,6 +500,11 @@ int hio_sys_ctrlmux (hio_t* hio, hio_sys_mux_cmd_t cmd, hio_dev_t* dev, int dev_
|
|||||||
int x;
|
int x;
|
||||||
|
|
||||||
HIO_ASSERT (hio, hio == dev->hio);
|
HIO_ASSERT (hio, hio == dev->hio);
|
||||||
|
|
||||||
|
/* no operation over a broken(closed) handle to prevent multiplexer from failing.
|
||||||
|
* close of the handle leads to auto-deletion from the epoll multiplexer.
|
||||||
|
* the closed handle must not be fed to the multiplexer */
|
||||||
|
if (dev->dev_mth->issyshndbroken && dev->dev_mth->issyshndbroken(dev)) return 0;
|
||||||
hnd = dev->dev_mth->getsyshnd(dev);
|
hnd = dev->dev_mth->getsyshnd(dev);
|
||||||
|
|
||||||
events = 0;
|
events = 0;
|
||||||
|
@ -568,6 +568,7 @@ static hio_dev_mth_t dev_thr_methods =
|
|||||||
dev_thr_kill_master,
|
dev_thr_kill_master,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
dev_thr_getsyshnd,
|
dev_thr_getsyshnd,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
HIO_NULL,
|
HIO_NULL,
|
||||||
@ -581,6 +582,7 @@ static hio_dev_mth_t dev_thr_methods_slave =
|
|||||||
dev_thr_kill_slave,
|
dev_thr_kill_slave,
|
||||||
dev_thr_fail_before_make_slave,
|
dev_thr_fail_before_make_slave,
|
||||||
dev_thr_getsyshnd_slave,
|
dev_thr_getsyshnd_slave,
|
||||||
|
HIO_NULL,
|
||||||
|
|
||||||
dev_thr_read_slave,
|
dev_thr_read_slave,
|
||||||
dev_thr_write_slave,
|
dev_thr_write_slave,
|
||||||
|
Loading…
Reference in New Issue
Block a user