static void ngx_http_hustdb_ha_exit_master(ngx_cycle_t * cycle)
{
    // TODO: uninitialize in master process
    if (g_mcf->disable_sync || !g_libsync)
    {
        return;
    }
    typedef ngx_bool_t (*libsync_stop_sync_t)();
    libsync_stop_sync_t stop_sync = dlsym(g_libsync, "stop_sync");
    char * error = dlerror();
    if(!error)
    {
        stop_sync();
    }
    dlclose(g_libsync);
}
void dal_i2c_sw_engine_submit_channel_request(
	struct i2c_engine *engine,
	struct i2c_request_transaction_data *req)
{
	struct i2c_sw_engine *sw_engine = FROM_I2C_ENGINE(engine);

	struct ddc *ddc = engine->base.ddc;
	uint16_t clock_delay_div_4 = sw_engine->clock_delay >> 2;

	/* send sync (start / repeated start) */

	bool result = start_sync(engine->base.ctx, ddc, clock_delay_div_4);

	/* process payload */

	if (result) {
		switch (req->action) {
		case I2CAUX_TRANSACTION_ACTION_I2C_WRITE:
		case I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT:
			result = i2c_write(engine->base.ctx, ddc, clock_delay_div_4,
				req->address, req->length, req->data);
		break;
		case I2CAUX_TRANSACTION_ACTION_I2C_READ:
		case I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT:
			result = i2c_read(engine->base.ctx, ddc, clock_delay_div_4,
				req->address, req->length, req->data);
		break;
		default:
			result = false;
		break;
		}
	}

	/* send stop if not 'mot' or operation failed */

	if (!result ||
		(req->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
		(req->action == I2CAUX_TRANSACTION_ACTION_I2C_READ))
		if (!stop_sync(engine->base.ctx, ddc, clock_delay_div_4))
			result = false;

	req->status = result ?
		I2C_CHANNEL_OPERATION_SUCCEEDED :
		I2C_CHANNEL_OPERATION_FAILED;
}