/* we don't need to clean up on err, as we'll go through the node struct and clean all we have inside */ static int _connection_process (connection_queue_t *node) { refbuf_t *header; http_parser_t *parser = NULL; int hdrsize = 0; int shoutcast = 0; int err; char *shoutcast_mount = NULL; mount_proxy *mountinfo; ice_config_t *config; listener_t *listener; if (!node->refbuf) node->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE); header = node->refbuf; { /* this code tests for shoutcastness */ config = config_get_config(); listener = config_get_listen_sock (config, node->con); if (listener) { WARN("listner"); if (listener->shoutcast_compat) shoutcast = 1; if (listener->ssl && ssl_ok) connection_uses_ssl (node->con); if (listener->shoutcast_mount) { shoutcast_mount = strdup (listener->shoutcast_mount); } else { shoutcast_mount = config->shoutcast_mount; } } WARN("shoutcast %d, mount %s", shoutcast, shoutcast_mount); mountinfo = config_find_mount (config, shoutcast_mount); config_release_config(); } if (shoutcast && !header->sync_point) { /* stage2 is actually handled by generic code */ err = _handle_shoutcast_stage1 (node, shoutcast_mount, mountinfo); if (err < 0) return err; } hdrsize = util_read_header (node->con, header, HEADER_READ_ENTIRE); if (hdrsize < 0) { ERROR ("Header read failed"); return hdrsize; } /* process normal HTTP headers */ if (node->parser) { parser = node->parser; } else { parser = node->parser = httpp_create_parser(); httpp_initialize(parser, NULL); } err = httpp_parse (parser, header->data, hdrsize); if (err == 0) { ERROR0("HTTP request parsing failed"); return -EINVAL; } /* XXX what happens when error in http ??? is err set ? */ if (httpp_getvar (parser, HTTPP_VAR_ERROR_MESSAGE)) { ERROR("Error(%s)", httpp_getvar(parser, HTTPP_VAR_ERROR_MESSAGE)); return err; } if (header->sync_point && (parser->req_type == httpp_req_source || parser->req_type == httpp_req_post)) { hdrsize = util_read_header (node->con, header, HEADER_READ_ENTIRE); if (hdrsize < 0) { INFO ("Header read failed"); return hdrsize; } } if (! node->client) { err = connection_client_setup (node); if (err < 0) return err; header->len -= hdrsize; if (header->len) { memmove(header->data, header->data + hdrsize, header->len); client_set_queue (node->client, header); } refbuf_release(header); } stats_event_inc (NULL, "connections"); WARN("shoutcast = %d", shoutcast); return _handle_client (node->client); }
// PSL thread loop static void *_psl_loop(void *ptr) { struct psl *psl = (struct psl *)ptr; struct cmd_event *event, *temp; int events, i, stopped, reset; uint8_t ack = PSLSE_DETACH; stopped = 1; pthread_mutex_lock(psl->lock); while (psl->state != PSLSE_DONE) { // idle_cycles continues to generate clock cycles for some // time after the AFU has gone idle. Eventually clocks will // not be presented to an idle AFU to keep simulation // waveforms from getting huge with no activity cycles. if (psl->state != PSLSE_IDLE) { psl->idle_cycles = PSL_IDLE_CYCLES; if (stopped) info_msg("Clocking %s", psl->name); fflush(stdout); stopped = 0; } if (psl->idle_cycles) { // Clock AFU psl_signal_afu_model(psl->afu_event); // Check for events from AFU events = psl_get_afu_events(psl->afu_event); // Error on socket if (events < 0) { warn_msg("Lost connection with AFU"); break; } // Handle events from AFU if (events > 0) _handle_afu(psl); // Drive events to AFU send_job(psl->job); send_mmio(psl->mmio); if (psl->mmio->list == NULL) psl->idle_cycles--; } else { if (!stopped) info_msg("Stopping clocks to %s", psl->name); stopped = 1; lock_delay(psl->lock); } // Skip client section if AFU descriptor hasn't been read yet if (psl->client == NULL) { lock_delay(psl->lock); continue; } // Check for event from application reset = 0; for (i = 0; i < psl->max_clients; i++) { if (psl->client[i] == NULL) continue; if ((psl->client[i]->state == CLIENT_NONE) && (psl->client[i]->idle_cycles == 0)) { put_bytes(psl->client[i]->fd, 1, &ack, psl->dbg_fp, psl->dbg_id, psl->client[i]->context); _free(psl, psl->client[i]); psl->client[i] = NULL; reset = 1; continue; } if (psl->state == PSLSE_RESET) continue; _handle_client(psl, psl->client[i]); if (psl->client[i]->idle_cycles) { psl->client[i]->idle_cycles--; } if (client_cmd(psl->cmd, psl->client[i])) { psl->client[i]->idle_cycles = PSL_IDLE_CYCLES; } } // Send reset to AFU if (reset == 1) { psl->cmd->buffer_read = NULL; event = psl->cmd->list; while (event != NULL) { if (reset) { warn_msg ("Client dropped context before AFU completed"); reset = 0; } warn_msg("Dumping command tag=0x%02x", event->tag); if (event->data) { free(event->data); } if (event->parity) { free(event->parity); } temp = event; event = event->_next; free(temp); } psl->cmd->list = NULL; info_msg("Sending reset to AFU"); add_job(psl->job, PSL_JOB_RESET, 0L); } lock_delay(psl->lock); } // Disconnect clients for (i = 0; i < psl->max_clients; i++) { if ((psl->client != NULL) && (psl->client[i] != NULL)) { // FIXME: Send warning to clients first? info_msg("Disconnecting %s context %d", psl->name, psl->client[i]->context); close_socket(&(psl->client[i]->fd)); } } // DEBUG debug_afu_drop(psl->dbg_fp, psl->dbg_id); // Disconnect from simulator, free memory and shut down thread info_msg("Disconnecting %s @ %s:%d", psl->name, psl->host, psl->port); if (psl->client) free(psl->client); if (psl->_prev) psl->_prev->_next = psl->_next; if (psl->_next) psl->_next->_prev = psl->_prev; if (psl->cmd) { free(psl->cmd); } if (psl->job) { free(psl->job); } if (psl->mmio) { free(psl->mmio); } if (psl->host) free(psl->host); if (psl->afu_event) { psl_close_afu_event(psl->afu_event); free(psl->afu_event); } if (psl->name) free(psl->name); if (*(psl->head) == psl) *(psl->head) = psl->_next; pthread_mutex_unlock(psl->lock); free(psl); pthread_exit(NULL); }
// PSL thread loop static void *_psl_loop(void *ptr) { struct psl *psl = (struct psl *)ptr; struct cmd_event *event, *temp; int events, i, stopped, reset; uint8_t ack = PSLSE_DETACH; stopped = 1; pthread_mutex_lock(psl->lock); while (psl->state != PSLSE_DONE) { // idle_cycles continues to generate clock cycles for some // time after the AFU has gone idle. Eventually clocks will // not be presented to an idle AFU to keep simulation // waveforms from getting huge with no activity cycles. if (psl->state != PSLSE_IDLE) { // if we have clients or we are in the reset state, refresh idle_cycles // so that the afu clock will not be allowed to stop to save afu event simulator cycles if ((psl->attached_clients > 0) || (psl->state == PSLSE_RESET)) { psl->idle_cycles = PSL_IDLE_CYCLES; if (stopped) info_msg("Clocking %s", psl->name); fflush(stdout); stopped = 0; } } if (psl->idle_cycles) { // Clock AFU //printf("before psl_signal_afu_model in psl_loop \n"); psl_signal_afu_model(psl->afu_event); // Check for events from AFU events = psl_get_afu_events(psl->afu_event); //printf("after psl_get_afu_events, events is 0x%3x \n", events); // Error on socket if (events < 0) { warn_msg("Lost connection with AFU"); break; } // Handle events from AFU if (events > 0) _handle_afu(psl); // Drive events to AFU send_job(psl->job); send_pe(psl->job); send_mmio(psl->mmio); if (psl->mmio->list == NULL) psl->idle_cycles--; } else { if (!stopped) info_msg("Stopping clocks to %s", psl->name); stopped = 1; lock_delay(psl->lock); } // Skip client section if AFU descriptor hasn't been read yet if (psl->client == NULL) { lock_delay(psl->lock); continue; } // Check for event from application reset = 0; for (i = 0; i < psl->max_clients; i++) { if (psl->client[i] == NULL) continue; if ((psl->client[i]->type == 'd') && (psl->client[i]->state == CLIENT_NONE) && (psl->client[i]->idle_cycles == 0)) { // this was the old way of detaching a dedicated process app/afu pair // we get the detach message, drop the client, and wait for idle cycle to get to 0 put_bytes(psl->client[i]->fd, 1, &ack, psl->dbg_fp, psl->dbg_id, psl->client[i]->context); _free(psl, psl->client[i]); psl->client[i] = NULL; // aha - this is how we only called _free once the old way // why do we not free client[i]? // because this was a short cut pointer // the *real* client point is in client_list in pslse reset = 1; // for m/s devices we need to do this differently and not send a reset... // _handle_client - creates the llcmd's to term and remove // send_pe - sends the llcmd pe's to afu one at a time // _handle_afu calls _handle_aux2 // _handle_aux2 finishes the llcmd pe's when jcack is asserted by afu // when the remove llcmd is processed, we should put_bytes, _free and set client[i] to NULL continue; } if (psl->state == PSLSE_RESET) continue; _handle_client(psl, psl->client[i]); if (psl->client[i]->idle_cycles) { psl->client[i]->idle_cycles--; } if (client_cmd(psl->cmd, psl->client[i])) { psl->client[i]->idle_cycles = PSL_IDLE_CYCLES; } } // Send reset to AFU if (reset == 1) { psl->cmd->buffer_read = NULL; event = psl->cmd->list; while (event != NULL) { if (reset) { warn_msg ("Client dropped context before AFU completed"); reset = 0; } info_msg("Dumping command tag=0x%02x", event->tag); #ifdef PSL9 info_msg("Dumping itag=0x%02x utag=0x%02x type=0x%02x state=0x%02x", event->itag, event->utag, event->type, event->state); #endif if (event->data) { free(event->data); } if (event->parity) { free(event->parity); } temp = event; event = event->_next; free(temp); } psl->cmd->list = NULL; info_msg("Sending reset to AFU"); add_job(psl->job, PSL_JOB_RESET, 0L); } lock_delay(psl->lock); } // Disconnect clients for (i = 0; i < psl->max_clients; i++) { if ((psl->client != NULL) && (psl->client[i] != NULL)) { // FIXME: Send warning to clients first? info_msg("Disconnecting %s context %d", psl->name, psl->client[i]->context); close_socket(&(psl->client[i]->fd)); } } // DEBUG debug_afu_drop(psl->dbg_fp, psl->dbg_id); // Disconnect from simulator, free memory and shut down thread info_msg("Disconnecting %s @ %s:%d", psl->name, psl->host, psl->port); if (psl->client) free(psl->client); if (psl->_prev) psl->_prev->_next = psl->_next; if (psl->_next) psl->_next->_prev = psl->_prev; if (psl->cmd) { free(psl->cmd); } if (psl->job) { free(psl->job); } if (psl->mmio) { free(psl->mmio); } if (psl->host) free(psl->host); if (psl->afu_event) { psl_close_afu_event(psl->afu_event); free(psl->afu_event); } if (psl->name) free(psl->name); if (*(psl->head) == psl) *(psl->head) = psl->_next; pthread_mutex_unlock(psl->lock); free(psl); pthread_exit(NULL); }