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);
|
||||
*/
|
||||
|
||||
marc = hio_svc_marc_start(hio, &ci, HIO_NULL);
|
||||
marc = hio_svc_marc_start(hio, &ci, HIO_NULL, HIO_NULL);
|
||||
if (!marc)
|
||||
{
|
||||
printf ("Cannot start a mariadb client service\n");
|
||||
|
@ -125,6 +125,8 @@ struct hio_dev_mar_make_t
|
||||
{
|
||||
int flags;
|
||||
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_read_t on_read; /* mandatory */
|
||||
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_t* hio,
|
||||
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 (
|
||||
|
@ -222,7 +222,8 @@ struct hio_dev_mth_t
|
||||
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.
|
||||
|
@ -45,6 +45,8 @@ struct hio_svc_marc_t
|
||||
int stopping;
|
||||
int tmout_set;
|
||||
|
||||
const hio_bch_t* default_group;
|
||||
|
||||
hio_svc_marc_connect_t ci;
|
||||
hio_svc_marc_tmout_t tmout;
|
||||
|
||||
@ -90,7 +92,7 @@ struct dev_xtn_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;
|
||||
|
||||
@ -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_set = 1;
|
||||
}
|
||||
marc->default_group = default_group;
|
||||
|
||||
HIO_SVCL_APPEND_SVC (&hio->actsvc, (hio_svc_t*)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.tmout = marc->tmout;
|
||||
}
|
||||
mi.default_group = marc->default_group;
|
||||
|
||||
mi.on_connect = mar_on_connect;
|
||||
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;
|
||||
|
||||
xtn = (dev_xtn_t*)hio_dev_mar_getxtn(mar);
|
||||
xtn->sid = sid;
|
||||
xtn->svc = marc;
|
||||
xtn->sid = sid;
|
||||
|
||||
if (hio_dev_mar_connect(mar, &marc->ci) <= -1)
|
||||
{
|
||||
/* connection failed immediately */
|
||||
xtn->sid = INVALID_SID;
|
||||
hio_dev_mar_halt (mar);
|
||||
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];
|
||||
HIO_ASSERT (hio, sess->sid == sid);
|
||||
HIO_ASSERT (hio, sess->svc == marc);
|
||||
HIO_ASSERT (hio, sess->sid == sid);
|
||||
|
||||
if (!sess->dev)
|
||||
{
|
||||
|
@ -52,6 +52,9 @@ static int dev_mar_make (hio_dev_t* dev, void* ctx)
|
||||
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)
|
||||
{
|
||||
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->broken = 0;
|
||||
rdev->broken_syshnd = HIO_SYSHND_INVALID;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
{
|
||||
/* 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));
|
||||
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);
|
||||
rdev->connected_deferred = 1; /* to let the ready() handler to trigger on_connect() */
|
||||
/* 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() */
|
||||
const hio_ooch_t* prev_errmsg;
|
||||
prev_errmsg = hio_backuperrmsg(hio);
|
||||
|
||||
rdev->connected = 0;
|
||||
rdev->broken = 1;
|
||||
/* remember the previous handle - this may be needed by the poll/select based multiplexer */
|
||||
rdev->broken_syshnd = syshnd;
|
||||
|
||||
watch_mysql (rdev, 0);
|
||||
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);
|
||||
@ -335,6 +354,7 @@ static hio_dev_mth_t dev_mar_methods =
|
||||
dev_mar_kill,
|
||||
HIO_NULL,
|
||||
dev_mar_getsyshnd,
|
||||
dev_mar_issyshndbroken,
|
||||
|
||||
HIO_NULL,
|
||||
HIO_NULL,
|
||||
@ -416,8 +436,16 @@ static int dev_evcb_mar_ready (hio_dev_t* dev, int events)
|
||||
{
|
||||
/* 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_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().
|
||||
* 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,
|
||||
HIO_NULL,
|
||||
dev_pipe_getsyshnd,
|
||||
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_fail_before_make_slave,
|
||||
dev_pipe_getsyshnd_slave,
|
||||
HIO_NULL,
|
||||
|
||||
dev_pipe_read_slave,
|
||||
dev_pipe_write_slave,
|
||||
|
@ -738,6 +738,7 @@ static hio_dev_mth_t dev_pro_methods =
|
||||
dev_pro_kill_master,
|
||||
HIO_NULL,
|
||||
dev_pro_getsyshnd,
|
||||
HIO_NULL,
|
||||
|
||||
HIO_NULL, /* read */
|
||||
HIO_NULL, /* write */
|
||||
@ -752,6 +753,7 @@ static hio_dev_mth_t dev_pro_methods_slave =
|
||||
dev_pro_kill_slave,
|
||||
HIO_NULL,
|
||||
dev_pro_getsyshnd_slave,
|
||||
HIO_NULL,
|
||||
|
||||
dev_pro_read_slave,
|
||||
dev_pro_write_slave,
|
||||
|
@ -1398,6 +1398,7 @@ static hio_dev_mth_t dev_mth_sck_stateless =
|
||||
dev_sck_kill,
|
||||
HIO_NULL,
|
||||
dev_sck_getsyshnd,
|
||||
HIO_NULL,
|
||||
|
||||
dev_sck_read_stateless,
|
||||
dev_sck_write_stateless,
|
||||
@ -1413,6 +1414,7 @@ static hio_dev_mth_t dev_mth_sck_stateful =
|
||||
dev_sck_kill,
|
||||
HIO_NULL,
|
||||
dev_sck_getsyshnd,
|
||||
HIO_NULL,
|
||||
|
||||
dev_sck_read_stateful,
|
||||
dev_sck_write_stateful,
|
||||
@ -1427,6 +1429,7 @@ static hio_dev_mth_t dev_mth_clisck =
|
||||
dev_sck_kill,
|
||||
dev_sck_fail_before_make_client,
|
||||
dev_sck_getsyshnd,
|
||||
HIO_NULL,
|
||||
|
||||
dev_sck_read_stateful,
|
||||
dev_sck_write_stateful,
|
||||
@ -1441,6 +1444,7 @@ static hio_dev_mth_t dev_mth_sck_bpf =
|
||||
dev_sck_kill,
|
||||
HIO_NULL,
|
||||
dev_sck_getsyshnd,
|
||||
HIO_NULL,
|
||||
|
||||
dev_sck_read_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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
events = 0;
|
||||
|
@ -568,6 +568,7 @@ static hio_dev_mth_t dev_thr_methods =
|
||||
dev_thr_kill_master,
|
||||
HIO_NULL,
|
||||
dev_thr_getsyshnd,
|
||||
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_fail_before_make_slave,
|
||||
dev_thr_getsyshnd_slave,
|
||||
HIO_NULL,
|
||||
|
||||
dev_thr_read_slave,
|
||||
dev_thr_write_slave,
|
||||
|
Loading…
Reference in New Issue
Block a user