/**
 * \fn void rq_state_start_stream(void)
 * \brief Send the command to start the streaming mode
 *        If the stream doesn't start, return to state init.
 *        Set the next state to \ref RQ_STATE_RUN
 */
static void rq_state_start_stream()
{
	if(rq_com_start_stream() == -1)
	{
#if defined(_WIN32)||defined(WIN32) //For Windows
		stop_connection();
#endif
		current_state = RQ_STATE_INIT;
	}
	current_state = RQ_STATE_RUN;
}
示例#2
0
/**
 * @brief read from a connection
 */
void *connection_reader(void *arg) {
  
  struct message *msg;
  conn_node *c;
  
  c=(conn_node *) arg;
  
#ifndef NDEBUG
  print( DEBUG, "started (fd=%d, tid=%lu)", c->fd, pthread_self() );
#endif
  
  while((msg = read_message(c->fd))) {
    pthread_mutex_lock(&(c->control.mutex));
    
    while(c->freeze) {
      pthread_cond_wait(&(c->control.cond), &(c->control.mutex));
    }
    
    pthread_mutex_unlock(&(c->control.mutex));
    
    if(enqueue_message(&(c->incoming), msg)) {
      print( ERROR, "cannot enqueue received message" );
      dump_message(msg);
      free_message(msg);
    }
  }
  
  stop_connection(c);
  
  pthread_mutex_lock(&(c->control.mutex));
  while(!c->writer_done || !c->worker_done) {
    pthread_cond_wait(&(c->control.cond), &(c->control.mutex));
  }
  pthread_mutex_unlock(&(c->control.mutex));
  
  pthread_mutex_lock(&(connections.control.mutex));
  list_del(&(connections.list), (node *)c);
  pthread_mutex_unlock(&(connections.control.mutex));
  
  pthread_cond_broadcast(&(connections.control.cond));
  
  close(c->fd);

#ifndef NDEBUG
  print( DEBUG, "connection closed (fd=%d)", c->fd );
#endif
  
  // add me to the death list
  send_me_to_graveyard();
  
  free_connection(c);
  
  return 0;
}
/**
 * \fn void rq_state_run()
 * \brief Capture and read the stream from the sensor.
 *        If the stream is not valid, return to state
 *        \ref RQ_STATE_INIT
 */
static void rq_state_run()
{
	rq_com_listen_stream();

	if(rq_com_get_valid_stream() == false)
	{
#if defined(_WIN32)||defined(WIN32) //For Windows
		stop_connection();
#endif
		current_state = RQ_STATE_INIT;
	}
}
示例#4
0
/**
 * @brief close all connections from ::connections
 */
void close_connections() {
  register conn_node *c;
  
  pthread_mutex_lock(&(connections.control.mutex));
  
  // equivalent to control_deactivate
  connections.control.active = 0;
  
  for(c=(conn_node *) connections.list.head;c;c=(conn_node *) c->next) {
    stop_connection(c);
  }
  
  // wait that all connection threads ends
  while(connections.list.head) {
    pthread_cond_wait(&(connections.control.cond), &(connections.control.mutex));
  }
  
  pthread_mutex_unlock(&(connections.control.mutex));
}
示例#5
0
/**
 * @brief start a @connection_handler for a new client.
 * @param fd file descriptor of the new client
 * @returns 0 on success, -1 on error.
 */
int serve_new_client(int fd) {
  conn_node *c;
  pthread_t dummy;
  int writer_created, worker_created;
  
  
  pthread_mutex_lock(&(connections.control.mutex));
  writer_created = connections.control.active; // OPTIMIZATION
  pthread_mutex_unlock(&(connections.control.mutex));
  
  if(!writer_created) {
    print( ERROR, "connections disabled" );
    return -1;
  }
  
  writer_created = worker_created = 0;
  
  c = malloc(sizeof(conn_node));
  
  if(!c) {
    print( ERROR, "malloc: %s", strerror(errno) );
    return -1;
  }

  memset(c, 0, sizeof(conn_node));
  
  if(control_init(&(c->control)) || control_init(&(c->incoming.control)) ||
    control_init(&(c->outcoming.control))) {
    print( ERROR, "cannot init cotnrols" );
    free_connection(c);
    return -1;
  }

  c->fd = fd;
  
  pthread_mutex_lock(&(connections.control.mutex));
  
  if( (writer_created = pthread_create(&dummy, NULL, &connection_writer, (void *)c)) ||
      (worker_created = pthread_create(&dummy, NULL, &connection_worker, (void *)c)) ||
      pthread_create(&dummy, NULL, &connection_reader, (void *)c)) {
    pthread_mutex_unlock(&(connections.control.mutex));
    print( ERROR, "pthread_create: %s", strerror(errno) );
    goto create_error;
  }
  
  list_add(&(connections.list), (node *) c);
  
  pthread_mutex_unlock(&(connections.control.mutex));

  pthread_cond_broadcast(&(connections.control.cond));
  
  return 0;
  
  create_error:
  
  if(writer_created || worker_created) {
    stop_connection(c);
    pthread_mutex_lock(&(c->control.mutex));
    while((writer_created && !c->writer_done) || (worker_created && !c->worker_done)) {
      pthread_cond_wait(&(c->control.cond), &(c->control.mutex));
    }
    pthread_mutex_unlock(&(c->control.mutex));
  }
  
  free_connection(c);
  
  return -1;
}