示例#1
0
/* 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);
}
示例#2
0
文件: psl.c 项目: open-cpu/pslse
// 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);
}
示例#3
0
文件: psl.c 项目: ibm-capi/pslse
// 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);
}