/** * Clone whole GWBUF list instead of single buffer. * * @param buf head of the list to be cloned till the tail of it * * @return head of the cloned list or NULL if the list was empty. */ GWBUF* gwbuf_clone_all( GWBUF* buf) { GWBUF* rval; GWBUF* clonebuf; if (buf == NULL) { return NULL; } /** Store the head of the list to rval. */ clonebuf = gwbuf_clone(buf); rval = clonebuf; while (buf->next) { buf = buf->next; clonebuf->next = gwbuf_clone(buf); clonebuf = clonebuf->next; } return rval; }
/** * Error Handler routine * * The routine will handle errors that occurred in backend writes. * * @param instance The router instance * @param router_session The router session * @param message The error message to reply * @param backend_dcb The backend DCB * @param action The action: REPLY, REPLY_AND_CLOSE, NEW_CONNECTION * */ static void handleError( ROUTER *instance, void *router_session, GWBUF *errbuf, DCB *backend_dcb, error_action_t action, bool *succp) { DCB *client_dcb; SESSION *session = backend_dcb->session; session_state_t sesstate; /** Reset error handle flag from a given DCB */ if (action == ERRACT_RESET) { backend_dcb->dcb_errhandle_called = false; return; } /** Don't handle same error twice on same DCB */ if (backend_dcb->dcb_errhandle_called) { /** we optimistically assume that previous call succeed */ *succp = true; return; } else { backend_dcb->dcb_errhandle_called = true; } spinlock_acquire(&session->ses_lock); sesstate = session->state; client_dcb = session->client; if (sesstate == SESSION_STATE_ROUTER_READY) { CHK_DCB(client_dcb); spinlock_release(&session->ses_lock); client_dcb->func.write(client_dcb, gwbuf_clone(errbuf)); } else { spinlock_release(&session->ses_lock); } /** false because connection is not available anymore */ *succp = false; }
/** * Send a reply to a command we have received from the slave. The reply itself * is merely a copy of a previous message we received from the master when we * registered as a slave. Hence we just replay this saved reply. * * @param router The binlog router instance * @param slave The slave server to which we are sending the response * @param master The saved master response * @return Non-zero if data was sent */ static int blr_slave_replay(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *master) { GWBUF *clone; if (!master) return 0; if ((clone = gwbuf_clone(master)) != NULL) { return slave->dcb->func.write(slave->dcb, clone); } else { LOGIF(LE, (skygw_log_write(LOGFILE_ERROR, "Failed to clone server response to send to slave."))); return 0; } }