Example #1
0
/**
 * Funkcia syncProcess vytvara procesy a synchronizuje ich.
 * @param param Struktura s vlastnostami pre procesy.
 * @return Chybovy navrat funkcie.
 */
int syncProcess(TParams *param)
{
  int error = EOK;           // Premmena pre chybu pri zdielanej pamati.
  param->mainpid = getpid(); // Proces id hlavneho programu.
  setSignals(getpid());      // Zachytenie signalov.
  signal(SIGCHLD, SIG_IGN);  // Ignorovanie sigchld a uvolnovanie procesov.

  // Inicializacia semaforov
  TMutx semaphores = {.mut0 = NULL, .mut1 = NULL, .mut2 = NULL ,.mut3 = NULL,
  .mut4 = NULL, .mut5 = NULL, .mut6 = NULL, .mut7 = NULL,};
  if(initSemaphores(&semaphores) != EOK)
  {
   destroySemaphores(&semaphores);
   return ESEMAP;
  }
  g_mutxs = &semaphores;

  // Vytvorenie zdielanej pamate.
  TSmem *memory = createSharedMem(&error,param,"/tmp");
  if(error) return ESHARED;
  g_mems = memory;
  g_shmid = param->sharedid;

  // Vytvorenie procesa holica.
  if((param->barberid = fork()) == -1)
  {
    destroySemaphores(&semaphores);
    unlinkSharedMem(memory,param->sharedid);
    return EFORK;
  }
  // Volanie holica.
  else if(param->barberid == 0)
  {
    syncBarber(memory, &semaphores, param);
    destroySemaphores(&semaphores);
    unlinkSharedMem(memory,param->sharedid);
    fclose(param->fw);
    exit(EXIT_SUCCESS);
  }
  // Vytvorenie procesov zakaznikov.
  else if(param->barberid > 0)
  {
    if(createCustomers(memory,param,&semaphores) == EFORK)
    {
      printECode(EFORK);
      kill(param->barberid, SIGUSR1);
      for(int i = 0; i < memory->created; i++)
        kill(memory->pids[0],SIGTERM);
      errorCleanAll(&semaphores,memory,param);
    }

    // Pockanie na proces barbra a uvolnenie zdielanej pamati.
    waitpid(param->barberid, NULL, 0);
    unlinkSharedMem(memory,param->sharedid);
    destroySemaphores(&semaphores);
  }
  return EOK;
}
Example #2
0
/**
 * Funkcia createCustomers vytvara zakaznikov.
 * @param shm Struktura zdielanej pamati.
 * @param param Struktura s parametrami programu.
 * @param smphrs Struktura so semaformi.
 */
int createCustomers(TSmem *shm, TParams *param, TMutx *smphrs)
{
  pid_t pid;                // PID pre zakaznika.
  int customerid = 0;       // Poradove cislo zakaznika.
  signal(SIGCHLD, SIG_IGN); // Ignorovanie sigchld a uvolnovanie procesov.

  // Vytvorenie zakaznikov.
  for(unsigned long int i = 0; i < param->customers; i++)
  {
    usleep(rand()%(param->t_interval+1)*TOMSECOND);
    if((pid = fork()) == -1)
      return EFORK;
    // Volanie zakaznika.
    else if(pid == 0)
    {
      shm->pids[i] = getpid();
      sem_wait(smphrs->mut7);
      setbuf(param->fw, NULL);
      fprintf(param->fw,"%d: customer %d: created\n",++(shm->action),
      ++(shm->created));
      customerid = shm->created;
      sem_post(smphrs->mut7);
      syncCustomer(shm,smphrs,customerid,param);
      unlinkSharedMem(shm,param->sharedid);
      destroySemaphores(smphrs);
      fclose(param->fw);
      exit(EXIT_SUCCESS);
    }
  }
  return EOK;
}
Example #3
0
void Thread::cancel(bool wait) {
  waiting = wait;
  cancelled = true;
  pthread_join(threadDescriptor, NULL);
  pthread_detach(threadDescriptor);
  destroySemaphores();
}
Example #4
0
/**
 * Funkcia errorCleanAll odstrani vytvorene procesy, semafory a pamat.
 * @param error Premenna urcujuca typ chyby.
 * @param smphrs Struktura pre semafory.
 * @param mem  Zdielana struktura.
 * @param param Struktura s doplnkovymi parametrami.
 */
void errorCleanAll(TMutx *smphrs, TSmem *mem, TParams *param)
{
  destroySemaphores(smphrs);
  unlinkSharedMem(mem,param->sharedid);
  fclose(param->fw);
  kill(param->mainpid, SIGTERM);
  exit(EXIT_FAILURE);
}
Example #5
0
/**
 * Funkcia killMain zasle signal sigterm hlavnemu procesu pri chybe.
 * @param signal Typ signalu.
 */
void killMain(int sig)
{
  destroySemaphores(g_mutxs);
  unlinkSharedMem(g_mems,g_shmid);
  if(g_fr != NULL)
    fclose(g_fr);
  signal(SIGTERM,SIG_DFL);
  kill(sig,getpid());
  exit(EXIT_FAILURE);
  return;
}
Example #6
0
int main(int argc, char const *argv[])
{
	if (argc != 2)
	{
		printf("usage: %s <data file>\n", argv[0]);
		exit(4);
	}

	int semaphores = getSemaphores();
	semaphoreWait(semaphores, WRITER);

	FILE* outputFile;
	outputFile = fopen(argv[1], "w");
	if (outputFile == 0)
	{
		printf("error: couldn't open output file");
		exit(5);
	}

	StudentInfo* basePointer = getSharedMemoryPointer();
	StudentInfo* currentPointer = basePointer;

	for (int i = 0; i < MAX_STUDENTS; ++i)
	{
		fprintf(outputFile, "%s\n", currentPointer->studentName);
		fprintf(outputFile, "%s\n", currentPointer->studentID);
		fprintf(outputFile, "%s\n", currentPointer->address);
		fprintf(outputFile, "%s\n", currentPointer->telephoneNumber);
		
		currentPointer++;
	}

	fclose(outputFile);

	detachSharedMemoryPointer(basePointer);

	destroySharedMemory();
	destroyReadCount();

	semaphoreSignal(semaphores, WRITER);

	destroySemaphores(semaphores);
	return 0;
}
Example #7
0
/**
 * Funkcia getParams spracuje argumenty z terminalu.
 * @param argc Pocet argumentov.
 * @param argv Argumenty.
 * @return Strukturu so spracovanymy vysledkami.
 */
TParams getParams(int argc, char *argv[])
{
  char *echar;  // Pomocna premmenna pre chybu v strtol().
  TParams param =
  {
    .error = 0, .state = 0, .filew = 0 , .chairs = 0,
    .t_interval = 0, .t_service = 0, .customers = 0, .fw = NULL,
  };

  // Zistenie ci je v programu napoveda.
  if(argc == 2)
  {
    if(argv[1][0] == '-' && argv[1][1] == 'h')
    {
      param.state = CHELP;
      return param;
    }
    else
      param.error = ECLWRONG;
  }
  else if(argc != PRMSCOUNT)
    param.error = ECLWRONG;

  // Spracovanie parametrov, prevod retazca na cislo pomocou strtol().
  if(param.error == EOK)
  {
    param.chairs = strtol(argv[1], &echar, DECIMAL);
    if(errno == ERANGE || *echar != '\0' || argv[1][0] == '-')
      param.error = ECLWRONG;
    param.t_interval = strtol(argv[2], &echar, DECIMAL);
    if(errno == ERANGE || *echar != '\0' || argv[2][0] == '-')
      param.error = ECLWRONG;
    param.t_service = strtol(argv[3], &echar, DECIMAL);
    if(errno == ERANGE || *echar != '\0' || argv[3][0] == '-')
      param.error = ECLWRONG;
    param.customers = strtol(argv[4], &echar, DECIMAL);
    if(errno == ERANGE || *echar != '\0' || argv[4][0] == '-')
      param.error = ECLWRONG;
    param.state = CFILE;

    // Zistenie ci je vystup do suboru.
    if(argv[5][0] == '-' && argv[5][1] == '\0')
      param.filew = CSTDOUT;
    else
      param.filew = CFILE;
  }
  return param;
}

/**
 * Funkcia killbarber ukonci barbra pri chybe.
 * @param sig Typ signalu.
 */
void killbarber(int sig)
{
  destroySemaphores(g_mutxs);
  unlinkSharedMem(g_mems,g_shmid);
  if(g_fr != NULL)
    fclose(g_fr);
  signal(sig, SIG_DFL);
  exit(EXIT_FAILURE);
  return;
}