static void _client_react(struct gridd_client_s *client) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); if (!client) return; GError *err = NULL; client->tv_step = oio_ext_monotonic_time (); retry: if (!(err = _client_manage_event(client))) { if (client->step == REP_READING_SIZE && client->reply && client->reply->len >= 4) goto retry; } else { _client_reset_request(client); _client_reset_reply(client); _client_reset_cnx(client); client->error = err; client->step = STATUS_FAILED; } }
static void _client_free(struct gridd_client_s *client) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); _client_reset_reply(client); _client_reset_request(client); _client_reset_cnx(client); _client_reset_target(client); _client_reset_error(client); if (client->reply) g_byte_array_free(client->reply, TRUE); client->fd = -1; SLICE_FREE (struct gridd_client_s, client); }
static GError* _client_request(struct gridd_client_s *client, GByteArray *req, gpointer ctx, client_on_reply cb) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); if ( NULL == req) return NEWERROR(CODE_INTERNAL_ERROR, "Invalid parameter"); switch (client->step) { case NONE: case CONNECTING: case CONNECTED: if (client->request != NULL) return NEWERROR(500, "Request already pending"); /* ok */ break; case REQ_SENDING: case REP_READING_SIZE: case REP_READING_DATA: return NEWERROR(500, "Request not terminated"); case STATUS_OK: case STATUS_FAILED: /* ok */ if (client->fd >= 0) client->step = REQ_SENDING; else client->step = CONNECTING; break; } /* if any, reset the last reply */ _client_reset_reply(client); _client_reset_request(client); _client_reset_error(client); /* Now set the new request components */ client->ctx = ctx; client->on_reply = cb; client->request = g_byte_array_ref(req); return NULL; }
static GError* _client_set_fd(struct gridd_client_s *client, int fd) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); if (fd >= 0) { switch (client->step) { case NONE: /* ok */ break; case CONNECTING: if (client->request != NULL) return NEWERROR(500, "Request pending"); /* PASSTHROUGH */ case CONNECTED: /* ok */ break; case REQ_SENDING: case REP_READING_SIZE: case REP_READING_DATA: return NEWERROR(500, "Request pending"); case STATUS_OK: case STATUS_FAILED: /* ok */ break; } } /* reset any connection and request */ _client_reset_reply(client); _client_reset_request(client); _client_reset_target(client); /* XXX do not call _client_reset_cnx(), or close the connexion. * It is the responsibility of the caller to manage this, because it * explicitely breaks the pending socket management. */ client->fd = fd; /* CONNECTING instead of CONNECTED helps coping with not yet * completely connected sockets */ client->step = (client->fd >= 0) ? CONNECTING : NONE; return NULL; }
static void _client_free(struct gridd_client_s *client) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); _client_reset_reply(client); _client_reset_request(client); _client_reset_cnx(client); _client_reset_target(client); _client_reset_error(client); if (client->reply) g_byte_array_free(client->reply, TRUE); if (client->past_url) g_string_free(client->past_url, TRUE); memset(client, 0, sizeof(*client)); client->fd = -1; g_free(client); }