Esempio n. 1
0
void * worker_loop(void * arg_void) {

  WorkerLoopArgs * arg = arg_void;
  
  StateMachine * stateMachine;
  DfaSet * dfaSet = arg->dfaSet;
  state_machine_id machine_id = arg->machine_id;
  readlock(dfaSet->lock, machine_id);

  DEBUG("Worker loop: %ld\n", machine_id);
  
  stateMachine = getSmash(dfaSet->smash, machine_id);

  assert(stateMachine->machine_id == machine_id);

  if(pthread_detach(stateMachine->worker_thread) != 0) {
    perror("pthread_detach");
  }

  readunlock(dfaSet->lock);
  inner_worker_loop(arg_void);

  writelock(dfaSet->lock, machine_id); 
  DEBUG("Freeing machine %ld\n", machine_id);

  freeSmash(dfaSet->smash, machine_id);
  writeunlock(dfaSet->lock);

  return 0;
}
Esempio n. 2
0
void *reader (void *args)
{
    rwargs *a = static_cast<rwargs *>(args);
    int d;

    do
    {
        readlock (a->lock, a->id);
        d = data;
        usleep (a->delay);
        readunlock (a->lock);
        RPMS_DEBUG( LOGNAME, "Reader" + rpms::convert<std::string>(a->id) + ": data = " + rpms::convert<std::string>(d) );
        usleep (a->delay);
    } while (d != 0);
    RPMS_DEBUG( LOGNAME, "Reader" + rpms::convert<std::string>(a->id) + ": finished" );
    return 0;
}
Esempio n. 3
0
void * run_request(DfaSet * dfaSet, state_machine_id machine_id) {
  void * ret;
  WorkerLoopArgs * worker_loop_args = malloc(sizeof(WorkerLoopArgs));
  StateMachine * machine;
  
  readlock(dfaSet->lock, 600);
  
  machine =  getSmash(dfaSet->smash, machine_id);
 
  worker_loop_args->dfaSet = dfaSet;
  worker_loop_args->machine_id = machine_id;
  
  machine->worker_thread = pthread_self();
  readunlock(dfaSet->lock);

  ret = inner_worker_loop(worker_loop_args);

  return (void*)ret;

}
Esempio n. 4
0
void * inner_worker_loop(void * arg_void) {

  WorkerLoopArgs * arg = arg_void;
  DfaSet * dfaSet = arg->dfaSet;
  const state_machine_id machine_id = arg->machine_id;

  int timeout = 0; /* Run through the loop immediately the first time around. */
  int state = 0;
  int first = 1;
  StateMachine* stateMachine;

  
  free(arg_void);

  readlock(dfaSet->lock, machine_id); 



  stateMachine = getSmash(dfaSet->smash, machine_id);

  pthread_mutex_lock(stateMachine->mutex);
  
  while(1) {
    int rc = 0;

    state_name i, state_idx = NULL_STATE; 
    
    /** @todo inner worker loop doesn't seem to 'do the right thing' with respect to timing */
    if(1|| !stateMachine->pending) {  /* If no pending messages, go to sleep */
      struct timeval now;
      struct timespec timeout_spec;

      pthread_cond_t * cond;
      pthread_mutex_t * mutex;
      
      long usec;

      cond = stateMachine->sleepCond;
      mutex = stateMachine->mutex;
      
      readunlock(dfaSet->lock);

      /* A note on locking: This loop maintains a read lock everywhere
	 except for this call to sleep, and upon termination when it
	 requires a write lock. */

      gettimeofday(&now, NULL);

      usec = now.tv_usec + timeout;

      if(usec > 1000000) {
	now.tv_sec++;
	usec-=1000000;
      }
      
      timeout_spec.tv_sec = now.tv_sec;
      timeout_spec.tv_nsec = 1000 * usec;
      

      rc =  pthread_cond_timedwait (cond, mutex, &timeout_spec );

      if(rc == EINVAL) {
	perror("pthread");
      } 
      
      readlock(dfaSet->lock, machine_id);     
      
      /* Some other thread may have invalidated our pointer while we
	 were sleeping witout a lock... no longer true, *but* since
	 our pointer is local to this thread, we still need to re-read
	 from the store.*/

      assert(stateMachine == getSmash(dfaSet->smash, machine_id));
    }

    DEBUG("Current State: %d, %d\n", stateMachine->current_state, NULL_STATE_TOMBSTONE);

    if(stateMachine->current_state == NULL_STATE_TOMBSTONE) {
      DEBUG("Freeing statemachine\n");
      break;
    }
    if(state != stateMachine->current_state) { first = 1; }
    state = stateMachine->current_state;
    stateMachine->message.type = stateMachine->current_state;
    timeout = 690000 +(int) (300000.0*rand()/(RAND_MAX+1.0)); 
    for(i = 0; i < dfaSet->state_count; i++) {
      if(dfaSet->states[i].name == stateMachine->current_state) {
	state_idx = i;
      }
    } 

    assert(state_idx != NULL_STATE);
    DEBUG("Worker loop for state machine: %ld still active\n", machine_id);

    int send = 1;
    if(dfaSet->states[state_idx].retry_fcn != NULL) {
      send = dfaSet->states[state_idx].retry_fcn(dfaSet, stateMachine, &(stateMachine->message), stateMachine->message_recipient);
    }
    if(send) {
      if(first) {
	first = 0;
      } else {
	printf("Resending message. Machine # %ld State # %d\n", stateMachine->machine_id, stateMachine->current_state);
      } 
      send_message(&(dfaSet->networkSetup), &(stateMachine->message), stateMachine->message_recipient);
    }

  }

  setSmash(dfaSet->smash, stateMachine->machine_id);
  pthread_mutex_unlock(stateMachine->mutex);
  readunlock(dfaSet->lock);
  return 0;

}