diff --git a/include/maxscale/modutil.h b/include/maxscale/modutil.h index 35a36d28f..99c01f59e 100644 --- a/include/maxscale/modutil.h +++ b/include/maxscale/modutil.h @@ -52,6 +52,15 @@ GWBUF* modutil_create_mysql_err_msg(int packet_number, const char *statemsg, const char *msg); +/** Struct used for tracking the state inside the modutil functions */ +typedef struct +{ + uint8_t state; +} modutil_state; + +/** Static initialization define for modutil_state */ +#define MODUTIL_STATE_INIT {0} + /** * @brief Count the number of EOF and ERR packets in the buffer. * @@ -59,19 +68,20 @@ GWBUF* modutil_create_mysql_err_msg(int packet_number, * whole packets. If partial packets are in the buffer, they are ignored. * The caller must handle the detection of partial packets in buffers. * - * On the first invocation, the value pointed by @c skip should be set to false. - * On all subsequent calls, for partial result sets, the function uses it to - * store the internal state. When the value pointed by @c skip is set to true, - * the next call must be done with only unprocessed packets in @c reply. + * Before the first invocation, the value pointed by the @c state parameter + * should be initialized with MODUTIL_STATE_INIT. All subsequent calls with a + * partially processed result set must be made with only unprocessed packets + * in @c reply. * * @param reply Buffer to use * @param n_found Number of previous found packets - * @param more Set to true of more results exist - * @param skip Internal state of the function used for handling large payloads. + * @param more Set to true if more results exist + * @param state Internal state of the function, NULL if the function is + * only called once per result set * * @return Total number of EOF and ERR packets including the ones already found */ -int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, bool* skip); +int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, modutil_state* state); mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string); diff --git a/server/core/modutil.cc b/server/core/modutil.cc index 3c83e3eb0..62dc72bba 100644 --- a/server/core/modutil.cc +++ b/server/core/modutil.cc @@ -636,13 +636,13 @@ GWBUF* modutil_get_complete_packets(GWBUF **p_readbuf) return complete; } -int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, bool* skip) +int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, modutil_state* state) { unsigned int len = gwbuf_length(reply); int eof = 0; int err = 0; size_t offset = 0; - bool skip_next = skip ? *skip : false; + bool skip_next = state ? state->state : false; while (offset < len) { @@ -689,9 +689,9 @@ int modutil_count_signal_packets(GWBUF *reply, int n_found, bool* more, bool* sk int total = err + eof + n_found; - if (skip) + if (state) { - *skip = skip_next; + state->state = skip_next; } return total; diff --git a/server/modules/routing/readwritesplit/readwritesplit.cc b/server/modules/routing/readwritesplit/readwritesplit.cc index 492324e60..5c0614843 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.cc +++ b/server/modules/routing/readwritesplit/readwritesplit.cc @@ -523,10 +523,10 @@ bool reply_is_complete(SRWBackend backend, GWBUF *buffer) else { bool more = false; - bool skip = backend->get_skip_packet(); + modutil_state state = backend->get_modutil_state(); int old_eof = backend->get_reply_state() == REPLY_STATE_RSET_ROWS ? 1 : 0; - int n_eof = modutil_count_signal_packets(buffer, old_eof, &more, &skip); - backend->set_skip_packet(skip); + int n_eof = modutil_count_signal_packets(buffer, old_eof, &more, &state); + backend->set_modutil_state(state); if (n_eof == 0) { diff --git a/server/modules/routing/readwritesplit/rwsplitsession.cc b/server/modules/routing/readwritesplit/rwsplitsession.cc index a7825e565..df02ee63c 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.cc +++ b/server/modules/routing/readwritesplit/rwsplitsession.cc @@ -17,7 +17,7 @@ RWBackend::RWBackend(SERVER_REF* ref): mxs::Backend(ref), m_reply_state(REPLY_STATE_DONE), - m_skip(false) + m_modutil_state(MODUTIL_STATE_INIT) { } @@ -35,14 +35,14 @@ void RWBackend::set_reply_state(reply_state_t state) m_reply_state = state; } -void RWBackend::set_skip_packet(bool state) +void RWBackend::set_modutil_state(const modutil_state& state) { - m_skip = state; + m_modutil_state = state; } -bool RWBackend::get_skip_packet() const +modutil_state RWBackend::get_modutil_state() const { - return m_skip; + return m_modutil_state; } bool RWBackend::execute_session_command() diff --git a/server/modules/routing/readwritesplit/rwsplitsession.hh b/server/modules/routing/readwritesplit/rwsplitsession.hh index 53a4daa68..b1e3c741c 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.hh +++ b/server/modules/routing/readwritesplit/rwsplitsession.hh @@ -15,6 +15,8 @@ #include "readwritesplit.hh" #include "rwsplit_ps.hh" +#include + /** Enum for tracking client reply state */ enum reply_state_t @@ -50,15 +52,15 @@ public: bool execute_session_command(); bool write(GWBUF* buffer, response_type type = EXPECT_RESPONSE); - void set_skip_packet(bool state); - bool get_skip_packet() const; + void set_modutil_state(const modutil_state& state); + modutil_state get_modutil_state() const; private: reply_state_t m_reply_state; BackendHandleMap m_ps_handles; /**< Internal ID to backend PS handle mapping */ - bool m_skip; /**< Used to store the state of the EOF packet - * calculation for result sets when the result - * contains very large rows */ + modutil_state m_modutil_state; /**< Used to store the state of the EOF packet + * calculation for result sets when the result + * contains very large rows */ }; typedef std::tr1::shared_ptr SRWBackend;