static int __attempt_send(struct homer_sender *hs, GString *gs) { int ret; ret = write(hs->socket.fd, gs->str, gs->len); if (ret == gs->len) { // full write g_string_free(gs, TRUE); return 0; } if (ret < 0) { if (errno != EWOULDBLOCK && errno != EAGAIN) { ilog(LOG_ERR, "Write error to Homer at %s: %s", endpoint_print_buf(&hs->endpoint), strerror(errno)); __reset(hs); return 1; } ilog(LOG_DEBUG, "Home write blocked"); // XXX use poller for blocked writes? return 2; } // partial write ilog(LOG_DEBUG, "Home write blocked (partial write)"); g_string_erase(gs, 0, ret); return 3; }
/* This is called from a tiny assembly stub. */ void __start1 (void *heap_limit) { unsigned ix; if (hardware_init_hook) hardware_init_hook (); /* Initialize memory */ if (__data_load != __data_start) memcpy (__data_start, __data_load, __bss_start - __data_start); memset (__bss_start, 0, __end - __bss_start); __heap_limit = heap_limit; if (software_init_hook) software_init_hook (); __INIT_SECTION__ (); /* I'm not sure how useful it is to have a fini_section in an embedded system. */ atexit (__FINI_SECTION__); ix = main (0, NULL, NULL); exit (ix); while (1) __reset (); }
static void __noreturn openrisc_restart_cpu(struct restart_handler *rst) { __reset(); /* not reached, __reset does not return */ /* Not reached */ hang(); }
void rbuf::reset() { dPrintf("()"); pthread_mutex_lock(&mutex); __reset(); pthread_mutex_unlock(&mutex); }
void rbuf::set_capacity(int cap) { dPrintf("(%d)", cap); pthread_mutex_lock(&mutex); if (p_data) delete[] p_data; p_data = new char[(capacity = cap)]; __reset(); pthread_mutex_unlock(&mutex); }
void rbuf::dealloc() { dPrintf("()"); pthread_mutex_lock(&mutex); if (p_data) delete[] p_data; p_data = NULL; capacity = 0; __reset(); pthread_mutex_unlock(&mutex); }
static int __established(struct homer_sender *hs) { char buf[16]; int ret; GString *gs; // test connection with a dummy read ret = read(hs->socket.fd, buf, sizeof(buf)); if (ret < 0) { if (errno != EWOULDBLOCK && errno != EAGAIN) { ilog(LOG_ERR, "Connection error from Homer at %s: %s", endpoint_print_buf(&hs->endpoint), strerror(errno)); __reset(hs); return -1; } } // XXX handle return data from Homer? if (hs->partial) { ilog(LOG_DEBUG, "dequeue partial packet to Homer"); ret = __attempt_send(hs, hs->partial); if (ret == 3 || ret == 2) // partial write or not sent at all return 0; if (ret == 1) // write error, takes care of deleting hs->partial return -1; // ret == 0 -> sent OK, drop through to unqueue g_string_free(hs->partial, TRUE); hs->partial = NULL; } // unqueue as much as we can while ((gs = g_queue_pop_head(&hs->send_queue))) { ilog(LOG_DEBUG, "dequeue send queue to Homer"); ret = __attempt_send(hs, gs); if (ret == 0) // everything sent OK continue; if (ret == 3) { // partial write hs->partial = gs; return 0; } g_queue_push_head(&hs->send_queue, gs); if (ret == 1) // write error return -1; // ret == 2 -> blocked return 0; } // everything unqueued return 0; }
static int __check_conn(struct homer_sender *hs, int ret) { if (ret == 0) { ilog(LOG_INFO, "Connection to Homer at %s has been established", endpoint_print_buf(&hs->endpoint)); hs->state = __established; return hs->state(hs); } if (ret == 1) { ilog(LOG_DEBUG, "connection to Homer is in progress"); hs->state = __in_progress; return 0; } ilog(LOG_ERR, "Failed to connect to Homer at %s: %s", endpoint_print_buf(&hs->endpoint), strerror(errno)); __reset(hs); return -1; }
/* worker */ static inline void __worker_inner(coolmic_simple_t *self) { enum coolmic_simple_running running; coolmic_shout_t *shout; coolmic_vumeter_t *vumeter; size_t vumeter_iter = 1; size_t vumeter_interval = 4; ssize_t ret; coolmic_vumeter_result_t vumeter_result; int error; if (self->need_reset) { if (__reset(self) != 0) { self->running = RUNNING_ERROR; return; } } running = self->running; coolmic_shout_ref(shout = self->shout); coolmic_vumeter_ref(vumeter = self->vumeter); pthread_mutex_unlock(&(self->lock)); __emit_cs_unlocked(self, &(self->thread), COOLMIC_SIMPLE_CS_CONNECTING, COOLMIC_ERROR_NONE); if ((error = coolmic_shout_start(shout)) != COOLMIC_ERROR_NONE) { running = RUNNING_STOPPED; __emit_error_unlocked(self, &(self->thread), error); __emit_cs_unlocked(self, &(self->thread), COOLMIC_SIMPLE_CS_CONNECTIONERROR, error); } else { __emit_cs_unlocked(self, &(self->thread), COOLMIC_SIMPLE_CS_CONNECTED, COOLMIC_ERROR_NONE); } while (running == RUNNING_STARTED) { coolmic_logging_log(COOLMIC_LOGGING_LEVEL_DEBUG, COOLMIC_ERROR_NONE, "Still running"); if ((error = coolmic_shout_iter(shout)) != COOLMIC_ERROR_NONE) { __emit_error_unlocked(self, &(self->thread), error); __emit_cs_unlocked(self, &(self->thread), COOLMIC_SIMPLE_CS_CONNECTIONERROR, error); break; } ret = coolmic_vumeter_read(vumeter, -1); coolmic_logging_log(COOLMIC_LOGGING_LEVEL_DEBUG, COOLMIC_ERROR_NONE, "VUmeter returned: %zi", ret); if (ret < 0) { __emit_error_unlocked(self, &(self->thread), COOLMIC_ERROR_GENERIC); break; } else if (ret > 0) { vumeter_iter++; } if (vumeter_interval && vumeter_iter == vumeter_interval) { vumeter_iter = 0; if (coolmic_vumeter_result(vumeter, &vumeter_result) == 0) { __emit_event_unlocked(self, COOLMIC_SIMPLE_EVENT_VUMETER_RESULT, &(self->thread), &vumeter_result, NULL); } } pthread_mutex_lock(&(self->lock)); if (vumeter_interval != self->vumeter_interval) { vumeter_interval = self->vumeter_interval; if (vumeter_interval) vumeter_iter = vumeter_interval - 1; } if (self->need_reset) if (__reset(self) != 0) self->running = RUNNING_ERROR; running = self->running; pthread_mutex_unlock(&(self->lock)); } pthread_mutex_lock(&(self->lock)); if (self->running != RUNNING_STOPPING) self->running = RUNNING_LOST; self->need_reset = 1; __emit_cs_locked(self, &(self->thread), COOLMIC_SIMPLE_CS_DISCONNECTING, COOLMIC_ERROR_NONE); coolmic_shout_stop(shout); __emit_cs_locked(self, &(self->thread), COOLMIC_SIMPLE_CS_DISCONNECTED, COOLMIC_ERROR_NONE); coolmic_shout_unref(shout); coolmic_vumeter_unref(vumeter); return; }