示例#1
0
文件: slave.c 项目: kubat/drqueue
void slave_consistency_process (struct slave_database *sdb) {
    int i;
    time_t now;

    while (1) {
        for (i=0; i<MAXTASKS; i++) {
            if ((sdb->comp->status.task[i].used)
                    //&& (sdb->comp->status.task[i].status != TASKSTATUS_LOADING)
                    && (kill(sdb->comp->status.task[i].pid,0) == -1))
            {
                now = time(NULL);
                if ((sdb->comp->status.task[i].status != TASKSTATUS_LOADING)
                        && now != -1
                        && ((now - sdb->comp->status.task[i].start_loading_time) < MAXTASKLOADINGTIME)) {
                    // Still loading... no timeout
                    continue;
                }
                // There is process registered as running, but not running. Or it could be loading but without the real process running after the timeout.
                semaphore_lock(sdb->semid);
                sdb->comp->status.task[i].used = 0;
                semaphore_release(sdb->semid);
                log_auto(L_WARNING,"Process registered as running was not running. Removed.");
            } else if ((sdb->comp->status.task[i].used)
                       && (sdb->comp->status.task[i].status == TASKSTATUS_LOADING))
            {
                // The process is already running but marked as loading. We have to update.
                semaphore_lock(sdb->semid);
                sdb->comp->status.task[i].status = TASKSTATUS_RUNNING;
                semaphore_release(sdb->semid);
                log_auto(L_DEBUG2,"Process previously loading is now running.");
            }
        }
        sleep (SLAVEDELAY);
    }
}
示例#2
0
/*
 *	Routine:	semaphore_dereference
 *
 *	Release a reference on a semaphore.  If this is the last reference,
 *	the semaphore data structure is deallocated.
 */
void
semaphore_dereference(
	semaphore_t		semaphore)
{
	uint32_t collisions;
	spl_t spl_level;

	if (semaphore == NULL)
		return;

	if (hw_atomic_sub(&semaphore->ref_count, 1) != 0)
		return;

	/*
	 * Last ref, clean up the port [if any]
	 * associated with the semaphore, destroy
	 * it (if still active) and then free
	 * the semaphore.
	 */
	ipc_port_t port = semaphore->port;

	if (IP_VALID(port)) {
		assert(!port->ip_srights);
		ipc_port_dealloc_kernel(port);
	}

	/*
	 * Lock the semaphore to lock in the owner task reference.
	 * Then continue to try to lock the task (inverse order).
	 */
	spl_level = splsched();
	semaphore_lock(semaphore);
	for (collisions = 0; semaphore->active; collisions++) {
		task_t task = semaphore->owner;

		assert(task != TASK_NULL);
		
		if (task_lock_try(task)) {
			semaphore_destroy_internal(task, semaphore);
			/* semaphore unlocked */
			splx(spl_level);
			task_unlock(task);
			goto out;
		}
		
		/* failed to get out-of-order locks */
		semaphore_unlock(semaphore);
		splx(spl_level);
		mutex_pause(collisions);
		spl_level = splsched();
		semaphore_lock(semaphore);
	}
	semaphore_unlock(semaphore);
	splx(spl_level);

 out:
	zfree(semaphore_zone, semaphore);
}
示例#3
0
void
netcmd_semaphore_lock (void)
{
  const int timeout_seconds = 600;
  if (!semaphore_lock (&netcmd_semaphore, timeout_seconds * 1000))
    msg (M_FATAL, "Cannot lock net command semaphore"); 
}
示例#4
0
/*
 *	Routine:	semaphore_destroy
 *
 *	Destroys a semaphore.  This call will only succeed if the
 *	specified task is the SAME task name specified at the semaphore's
 *	creation.
 *
 *	All threads currently blocked on the semaphore are awoken.  These
 *	threads will return with the KERN_TERMINATED error.
 */
kern_return_t
semaphore_destroy(
	task_t			task,
	semaphore_t		semaphore)
{
	int				old_count;
	spl_t			spl_level;


	if (task == TASK_NULL || semaphore == SEMAPHORE_NULL)
		return KERN_INVALID_ARGUMENT;

	/*
	 *  Disown semaphore
	 */
	task_lock(task);
	if (semaphore->owner != task) {
		task_unlock(task);
		return KERN_INVALID_ARGUMENT;
	}
	remqueue(&task->semaphore_list, (queue_entry_t) semaphore);
	semaphore->owner = TASK_NULL;
	task->semaphores_owned--;
	task_unlock(task);

	spl_level = splsched();
	semaphore_lock(semaphore);

	/*
	 *  Deactivate semaphore
	 */
	assert(semaphore->active);
	semaphore->active = FALSE;

	/*
	 *  Wakeup blocked threads  
	 */
	old_count = semaphore->count;
	semaphore->count = 0;

	if (old_count < 0) {
		wait_queue_wakeup64_all_locked(&semaphore->wait_queue,
					     SEMAPHORE_EVENT,
					     THREAD_RESTART,
					     TRUE);		/* unlock? */
	} else {
		semaphore_unlock(semaphore);
	}
	splx(spl_level);

	/*
	 *  Deallocate
	 *
	 *  Drop the semaphore reference, which in turn deallocates the
	 *  semaphore structure if the reference count goes to zero.
	 */
	ipc_port_dealloc_kernel(semaphore->port);
	semaphore_dereference(semaphore);
	return KERN_SUCCESS;
}
示例#5
0
void
check_tasks (struct computer_status *cstatus, int64_t semid) {
  int i;

  semaphore_lock (semid);

  cstatus->ntasks = 0;
  for (i=0;i<MAXTASKS;i++) {
    if (cstatus->task[i].used) {
      if (cstatus->task[i].status == TASKSTATUS_RUNNING) {
        /* If the task is LOADING then there is no process running yet */
        if (kill(cstatus->task[i].pid,0) == 0) { /* check if task is running */
          cstatus->ntasks++;
        } else {
          /* task is registered but not running */
          log_auto(L_WARNING,"Check tasks found no task where there should have been one.");
          cstatus->task[i].used = 0;
        }
      } else {
        // FIXME: LOADING or FINISHED ?
        cstatus->ntasks++;
      }
    }
  }

  semaphore_release (semid);
}
示例#6
0
void
semaphore_destroy_all(
	task_t			task)
{
	uint32_t count;
	spl_t spl_level;

	count = 0;
	task_lock(task);
	while (!queue_empty(&task->semaphore_list)) {
		semaphore_t semaphore;

		semaphore = (semaphore_t) queue_first(&task->semaphore_list);

		if (count == 0) 
			spl_level = splsched();
		semaphore_lock(semaphore);

		semaphore_destroy_internal(task, semaphore);
		/* semaphore unlocked */

		/* throttle number of semaphores per interrupt disablement */
		if (++count == SEMASPERSPL) {
			count = 0;
			splx(spl_level);
		}
	}
	if (count != 0)
		splx(spl_level);

	task_unlock(task);
}
示例#7
0
/*
 *	Routine:	semaphore_destroy
 *
 *	Destroys a semaphore and consume the caller's reference on the
 *	semaphore.
 */
kern_return_t
semaphore_destroy(
	task_t			task,
	semaphore_t		semaphore)
{
	spl_t spl_level;

	if (semaphore == SEMAPHORE_NULL)
		return KERN_INVALID_ARGUMENT;

	if (task == TASK_NULL) {
		semaphore_dereference(semaphore);
		return KERN_INVALID_ARGUMENT;
	}

	task_lock(task);
	spl_level = splsched();
	semaphore_lock(semaphore);

	if (semaphore->owner != task) {
		semaphore_unlock(semaphore);
		splx(spl_level);
		task_unlock(task);
		return KERN_INVALID_ARGUMENT;
	}
			
	semaphore_destroy_internal(task, semaphore);
	/* semaphore unlocked */

	splx(spl_level);
	task_unlock(task);

	semaphore_dereference(semaphore);
	return KERN_SUCCESS;
}
示例#8
0
/*
 *	Routine:	semaphore_reference
 *
 *	Take out a reference on a semaphore.  This keeps the data structure
 *	in existence (but the semaphore may be deactivated).
 */
void
semaphore_reference(
	semaphore_t		semaphore)
{
	spl_t			spl_level;

	spl_level = splsched();
	semaphore_lock(semaphore);

	semaphore->ref_count++;

	semaphore_unlock(semaphore);
	splx(spl_level);
}
std::tuple<VkResult, uint32_t> acquire_next_image(swapchain_type &swapchain,
		std::chrono::nanoseconds timeout,
		const semaphore::semaphore_type &semaphore,
		const fence::fence_type &fence) {
	uint32_t image_index;
	std::lock(internal::get_mutex(swapchain), internal::get_mutex(semaphore));
	std::lock_guard<std::mutex> swapchain_lock(internal::get_mutex(swapchain), std::adopt_lock);
	std::lock_guard<std::mutex> semaphore_lock(internal::get_mutex(semaphore), std::adopt_lock);
	std::lock_guard<std::mutex> fence_lock(internal::get_mutex(fence), std::adopt_lock);
	const VkResult result(vkAcquireNextImageKHR(
		internal::get_instance(*internal::get_parent(swapchain)),
		internal::get_instance(swapchain), timeout.count(),
		internal::get_instance(semaphore), internal::get_instance(fence),
		&image_index));
	return std::make_tuple(result, image_index);
}
示例#10
0
/*
 *	Routine:	semaphore_dereference
 *
 *	Release a reference on a semaphore.  If this is the last reference,
 *	the semaphore data structure is deallocated.
 */
void
semaphore_dereference(
	semaphore_t		semaphore)
{
	int			ref_count;
	spl_t			spl_level;

	if (semaphore != NULL) {
	    spl_level = splsched();
	    semaphore_lock(semaphore);

	    ref_count = --(semaphore->ref_count);

	    semaphore_unlock(semaphore);
	    splx(spl_level);

	    if (ref_count == 0) {
			assert(wait_queue_empty(&semaphore->wait_queue));
			zfree(semaphore_zone, semaphore);
	    }
	}
}
示例#11
0
/*
 *	Routine:	semaphore_wait_internal
 *
 *		Decrements the semaphore count by one.  If the count is
 *		negative after the decrement, the calling thread blocks
 *		(possibly at a continuation and/or with a timeout).
 *
 *	Assumptions:
 *		The reference
 *		A reference is held on the signal semaphore.
 */
kern_return_t
semaphore_wait_internal(
	semaphore_t		wait_semaphore,
	semaphore_t		signal_semaphore,
	mach_timespec_t		*wait_timep,
	void 			(*caller_cont)(kern_return_t))
{
	boolean_t			nonblocking;
	int					wait_result;
	spl_t				spl_level;
	kern_return_t		kr = KERN_ALREADY_WAITING;

	spl_level = splsched();
	semaphore_lock(wait_semaphore);

	/*
	 * Decide if we really have to wait.
	 */
	nonblocking = (wait_timep != (mach_timespec_t *)0) ?
		      (wait_timep->tv_sec == 0 && wait_timep->tv_nsec == 0) :
		      FALSE;

	if (!wait_semaphore->active) {
		kr = KERN_TERMINATED;
	} else if (wait_semaphore->count > 0) {
		wait_semaphore->count--;
		kr = KERN_SUCCESS;
	} else if (nonblocking) {
		kr = KERN_OPERATION_TIMED_OUT;
	} else {
		uint64_t	abstime;
		thread_t	self = current_thread();

		wait_semaphore->count = -1;  /* we don't keep an actual count */
		thread_lock(self);
		
		/*
		 * If it is a timed wait, calculate the wake up deadline.
		 */
		if (wait_timep != (mach_timespec_t *)0) {
			nanoseconds_to_absolutetime((uint64_t)wait_timep->tv_sec *
											NSEC_PER_SEC + wait_timep->tv_nsec, &abstime);
			clock_absolutetime_interval_to_deadline(abstime, &abstime);
		}
		else
			abstime = 0;

		(void)wait_queue_assert_wait64_locked(
					&wait_semaphore->wait_queue,
					SEMAPHORE_EVENT,
					THREAD_ABORTSAFE, abstime,
					self);
		thread_unlock(self);
	}
	semaphore_unlock(wait_semaphore);
	splx(spl_level);

	/*
	 * wait_semaphore is unlocked so we are free to go ahead and
	 * signal the signal_semaphore (if one was provided).
	 */
	if (signal_semaphore != SEMAPHORE_NULL) {
		kern_return_t signal_kr;

		/*
		 * lock the signal semaphore reference we got and signal it.
		 * This will NOT block (we cannot block after having asserted
		 * our intention to wait above).
		 */
		signal_kr = semaphore_signal_internal(signal_semaphore,
						      THREAD_NULL,
						      SEMAPHORE_SIGNAL_PREPOST);

		if (signal_kr == KERN_NOT_WAITING)
			signal_kr = KERN_SUCCESS;
		else if (signal_kr == KERN_TERMINATED) {
			/* 
			 * Uh!Oh!  The semaphore we were to signal died.
			 * We have to get ourselves out of the wait in
			 * case we get stuck here forever (it is assumed
			 * that the semaphore we were posting is gating
			 * the decision by someone else to post the
			 * semaphore we are waiting on).  People will
			 * discover the other dead semaphore soon enough.
			 * If we got out of the wait cleanly (someone
			 * already posted a wakeup to us) then return that
			 * (most important) result.  Otherwise,
			 * return the KERN_TERMINATED status.
			 */
			thread_t self = current_thread();

			clear_wait(self, THREAD_INTERRUPTED);
			kr = semaphore_convert_wait_result(self->wait_result);
			if (kr == KERN_ABORTED)
				kr = KERN_TERMINATED;
		}
	}
	
	/*
	 * If we had an error, or we didn't really need to wait we can
	 * return now that we have signalled the signal semaphore.
	 */
	if (kr != KERN_ALREADY_WAITING)
		return kr;

	/*
	 * Now, we can block.  If the caller supplied a continuation
	 * pointer of his own for after the block, block with the
	 * appropriate semaphore continuation.  Thiswill gather the
	 * semaphore results, release references on the semaphore(s),
	 * and then call the caller's continuation.
	 */
	if (caller_cont) {
		thread_t self = current_thread();

		self->sth_continuation = caller_cont;
		self->sth_waitsemaphore = wait_semaphore;
		self->sth_signalsemaphore = signal_semaphore;
		wait_result = thread_block((thread_continue_t)semaphore_wait_continue);
	}
	else {
		wait_result = thread_block(THREAD_CONTINUE_NULL);
	}

	return (semaphore_convert_wait_result(wait_result));
}
示例#12
0
/*
 *	Routine:	semaphore_signal_internal
 *
 *		Signals the semaphore as direct.  
 *	Assumptions:
 *		Semaphore is locked.
 */
kern_return_t
semaphore_signal_internal(
	semaphore_t		semaphore,
	thread_t		thread,
	int				options)
{
	kern_return_t kr;
	spl_t  spl_level;

	spl_level = splsched();
	semaphore_lock(semaphore);

	if (!semaphore->active) {
		semaphore_unlock(semaphore);
		splx(spl_level);
		return KERN_TERMINATED;
	}

	if (thread != THREAD_NULL) {
		if (semaphore->count < 0) {
			kr = wait_queue_wakeup64_thread_locked(
			        	&semaphore->wait_queue,
					SEMAPHORE_EVENT,
					thread,
					THREAD_AWAKENED,
					TRUE);  /* unlock? */
		} else {
			semaphore_unlock(semaphore);
			kr = KERN_NOT_WAITING;
		}
		splx(spl_level);
		return kr;
	} 

	if (options & SEMAPHORE_SIGNAL_ALL) {
		int old_count = semaphore->count;

		if (old_count < 0) {
			semaphore->count = 0;  /* always reset */
			kr = wait_queue_wakeup64_all_locked(
					&semaphore->wait_queue,
					SEMAPHORE_EVENT,
					THREAD_AWAKENED,
					TRUE);		/* unlock? */
		} else {
			if (options & SEMAPHORE_SIGNAL_PREPOST)
				semaphore->count++;
			semaphore_unlock(semaphore);
			kr = KERN_SUCCESS;
		}
		splx(spl_level);
		return kr;
	}
	
	if (semaphore->count < 0) {
		if (wait_queue_wakeup64_one_locked(
					&semaphore->wait_queue,
					SEMAPHORE_EVENT,
					THREAD_AWAKENED,
					FALSE) == KERN_SUCCESS) {
			semaphore_unlock(semaphore);
			splx(spl_level);
			return KERN_SUCCESS;
		} else
			semaphore->count = 0;  /* all waiters gone */
	}

	if (options & SEMAPHORE_SIGNAL_PREPOST) {
		semaphore->count++;
	}

	semaphore_unlock(semaphore);
	splx(spl_level);
	return KERN_NOT_WAITING;
}
示例#13
0
文件: slave.c 项目: kubat/drqueue
void launch_task (struct slave_database *sdb, uint16_t itask) {
    /* Here we get the job ready in the process task structure pointed by itask */
    int rc;
    pid_t task_pid,waiter_pid;
    extern char **environ;
    char *exec_path;
    struct task *ttask;

    logtool = DRQ_LOG_TOOL_SLAVE_TASK;
    ttask = malloc (sizeof(*ttask));
    memcpy(ttask,&sdb->comp->status.task[itask],sizeof(*ttask));
    logger_task = ttask;

    if ((waiter_pid = fork()) == 0) {
        //
        // WAITER PROCESS
        // This process reports the execution of the command itself
        //
        set_signal_handlers_child_launcher ();
        if ((task_pid = fork()) == 0) {
            //
            // TASK PROCESS
            // This process executes the task
            // This child also creates the directory for logging if it doesn't exist
            // and prepares the file descriptors so every output will be logged
            //

            const char *new_argv[4];
            int lfd;   /* logger fd */

#ifdef __CYGWIN

            new_argv[0] = SHELL_NAME;
            new_argv[1] = "-c";
            new_argv[2] = sdb->comp->status.task[itask].jobcmd;
            new_argv[3] = NULL;
            /*       new_argv[0] = SHELL_NAME; */
            /*       if ((new_argv[1] = malloc(MAXCMDLEN)) == NULL) */
            /*         exit (1); */
            /*       cygwin_conv_to_posix_path(sdb->comp->status.task[itask].jobcmd,(char*)new_argv[1]); */
            /*       new_argv[2] = NULL; */
#else

            new_argv[0] = SHELL_NAME;
            new_argv[1] = "-c";
            new_argv[2] = sdb->comp->status.task[itask].jobcmd;
            new_argv[3] = NULL;
#endif

            setpgid(0,0);  /* So this process doesn't receive signals from the others */
            set_signal_handlers_task_exec ();

            if ((lfd = log_dumptask_open (&sdb->comp->status.task[itask])) != -1) {
                // Log on the logger file whatever goes to stdout and stderr
                dup2 (lfd,STDOUT_FILENO);
                dup2 (lfd,STDERR_FILENO);
                close (lfd);
            }
            task_environment_set(&sdb->comp->status.task[itask]);

#ifdef __CYGWIN

            exec_path = SHELL_PATH;
            /*       exec_path = malloc(PATH_MAX); */
            /*       char *dr_bin = getenv("DRQUEUE_BIN"); */
            /*       if (dr_bin) { */
            /*         snprintf (exec_path,PATH_MAX,"%s/tcsh.exe",dr_bin); */
            /*       } */
#else

            exec_path = SHELL_PATH;
#endif

            execve(exec_path,(char*const*)new_argv,environ);
            // Wouldn't reach this point unless error on execve
            drerrno_system = errno;
            log_auto(L_ERROR,"launch_task(): error on execve. (%s)",strerror(drerrno_system));
            slave_exit(SIGINT);
        } else if (task_pid == -1) {
            log_auto(L_ERROR,"lauch_task(): Fork failed. Task not created.");

            //semaphore_lock(sdb->semid);
            //sdb->comp->status.task[itask].used = 0; /* We don't need the task anymore */
            //semaphore_release(sdb->semid);
        }

        // Then we set the process as loading
        // Later on, well make a check for every loading frame and if running change its status
        semaphore_lock(sdb->semid);
        sdb->comp->status.task[itask].status = TASKSTATUS_LOADING;
        sdb->comp->status.task[itask].start_loading_time = time(NULL);
        sdb->comp->status.task[itask].pid = task_pid;
        sdb->comp->status.ntasks = computer_ntasks (sdb->comp);
        sdb->comp->status.nrunning = computer_nrunning (sdb->comp);
        semaphore_release(sdb->semid);

        if (waitpid(task_pid,&rc,0) == -1) {
            // It forked on task_pid but waitpid says it doesn't exist.
            drerrno_system = errno;
            log_auto(L_ERROR,"lauch_task(): task process (%i) does not exist. (%s)",task_pid,strerror(drerrno_system));

            semaphore_lock(sdb->semid);
            sdb->comp->status.task[itask].used = 0; /* We don't need the task anymore */
            sdb->comp->status.ntasks = computer_ntasks (sdb->comp);
            sdb->comp->status.nrunning = computer_nrunning (sdb->comp);
            semaphore_release(sdb->semid);
            // FIXME: notify the master ?
        } else {
            // waitpid returned successfully
            /* We have to clean the task and send the info to the master */
            /* consider WIFSIGNALED(status), WTERMSIG(status), WEXITSTATUS(status) */
            /* we pass directly the status (translated to DR) to the master
            and he decides what to do with the frame */
            semaphore_lock(sdb->semid);
            sdb->comp->status.task[itask].exitstatus = 0;
            sdb->comp->status.task[itask].status = TASKSTATUS_FINISHED;
            sdb->comp->status.ntasks = computer_ntasks (sdb->comp);
            sdb->comp->status.nrunning = computer_nrunning (sdb->comp);
            if (WIFSIGNALED(rc)) {
                /* Process exited abnormally either killed by us or by itself (SIGSEGV) */
                /*  printf ("\n\nSIGNALED with %i\n",WTERMSIG(rc)); */
                sdb->comp->status.task[itask].exitstatus |= DR_SIGNALEDFLAG ;
                sdb->comp->status.task[itask].exitstatus |= WTERMSIG(rc);
                log_auto(L_INFO,"Task signaled");
            } else {
                if (WIFEXITED(rc)) {
                    /*   printf ("\n\nEXITED with %i\n",WEXITSTATUS(rc)); */
                    sdb->comp->status.task[itask].exitstatus |= DR_EXITEDFLAG ;
                    sdb->comp->status.task[itask].exitstatus |= WEXITSTATUS(rc);
                    /* printf ("\n\nEXITED with
                    %i\n",DR_WEXITSTATUS(sdb->comp->status.task[itask].exitstatus)); */
                    log_auto(L_INFO,"Task finished");
                } else {
                    log_auto(L_WARNING,"Task finished with rc = %i",rc);
                }
            }
            semaphore_release(sdb->semid);

            request_task_finished (sdb,itask);

            semaphore_lock(sdb->semid);
            sdb->comp->status.task[itask].used = 0; /* We don't need the task anymore */
            semaphore_release(sdb->semid);
        }

        exit (0);

    } else if (waiter_pid == -1) {
        log_auto(L_WARNING,"Fork failed for task waiter");
        semaphore_lock(sdb->semid);
        sdb->comp->status.task[itask].used = 0; /* We don't need the task anymore */
        semaphore_release(sdb->semid);
        exit (1);
    } else {
        // in this "else" waiter_pid actually contains the PID of the waiter process
    }
}
示例#14
0
文件: database.c 项目: Hyask/drqueue
int
database_save (struct database *wdb) {
  /* This function returns 1 on success and 0 on failure */
  /* It logs failure and maybe it should leave that task to the calling function */
  /* README : this function reads from the database memory without locking */
  struct database_hdr hdr;
  char *basedir;
  char dir[BUFFERLEN];
  char filename[BUFFERLEN];
  int fd;
  uint32_t c;

  // FIXME: this all filename guessing should be inside a function
  if ((basedir = getenv ("DRQUEUE_DB")) == NULL) {
    /* This should never happen because we check it at the beginning of the program */
    log_auto (L_ERROR,"database_save() : DRQUEUE_DB environment variable could not be found. Master db cannot be saved.");
    drerrno = DRE_NOENVROOT;
    return 0;
  }

  snprintf (dir, BUFFERLEN - 1, "%s", basedir);
  snprintf (filename, BUFFERLEN - 1, "%s/drqueue.db", dir);
  
  // Lock it
  semaphore_lock(wdb->semid);

  if (database_backup(wdb) == 0) {
    // FIXME: filename should be a value returned by a function
    log_auto (L_ERROR,"database_save() : there was an error while backing up old database. NOT SAVING current one. (file: %s)", filename);
  }

  // FIXME:
  // dbfd = database_file_open(filename)
  log_auto (L_INFO,"Storing DB into: '%s'",filename);

  if ((fd = open (filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
    if (errno == ENOENT) {
      /* If its because the directory does not exist we try creating it first */
#ifdef _WIN32
      if (mkdir (dir) == -1) {
#else
      if (mkdir (dir, 0775) == -1) {
#endif
        drerrno_system = errno;
        log_auto (L_WARNING,"Could not create database directory. Check permissions: %s. (%s)",
		  dir,strerror(drerrno_system));
        drerrno = DRE_COULDNOTCREATE;
        return 0;
      }
      if ((fd = open (filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) {
        log_auto (L_WARNING,"Could not open database file for writing. Check permissions: %s. (%s)",
                    filename,strerror(drerrno_system));
        drerrno = DRE_COULDNOTCREATE;
        return 0;
      }
    } else {
      /* could not open the file for other reasons */
      log_auto (L_WARNING,"Could not open database file for writing. Check permissions: %s",
                  filename);
      drerrno = DRE_COULDNOTCREATE;
      return 0;
    }
  }

  // FIXME: database_header_save()
  hdr.magic = DB_MAGIC;
  hdr.version = database_version_id();
  hdr.job_size = MAXJOBS;
  write_32b (fd, &hdr.magic);
  write_32b (fd, &hdr.version);
  write_16b (fd, &hdr.job_size);

  for (c = 0; c < hdr.job_size; c++) {
    logger_job = &wdb->job[c];
    if (!database_job_save (fd, &wdb->job[c])) {
      // FIXME: report
      log_auto (L_ERROR,"database_save(): error saving job number %i. (%s)",c,strerror(drerrno_system));
      return 0;
    }
  }
  logger_job = NULL;
  
  log_auto (L_INFO,"Database saved successfully.");

  semaphore_release(wdb->semid);
  // Unlock it

  return 1;
}

int
database_job_save_frames (int sfd, struct job *job) {
  int nframes = job_nframes (job);
  struct frame_info *fi;
  int i;

  if ((fi = attach_frame_shared_memory (job->fishmid)) == (void *) -1) {
    // Store empty frames in an attemp to save other jobs
    // FIXME: Warning CORRUPT
    struct frame_info fi2;
    job_frame_info_init (&fi2);
    for (i = 0; i < nframes; i++) {
      if (!send_frame_info (sfd, &fi2)) {
	return 0;
      }
    }
  } else {
    for (i = 0; i < nframes; i++) {
      if (!send_frame_info (sfd, &fi[i])) {
	detach_frame_shared_memory (fi);
	return 0;
      }
    }
    detach_frame_shared_memory (fi);
  }
  return 1;
}
示例#15
0
/*
 *	Routine:	semaphore_signal_internal
 *
 *		Signals the semaphore as direct.  
 *	Assumptions:
 *		Semaphore is locked.
 */
kern_return_t
semaphore_signal_internal(
	semaphore_t		semaphore,
	thread_t		thread,
	int				options)
{
	kern_return_t kr;
	spl_t  spl_level;

	spl_level = splsched();
	semaphore_lock(semaphore);

	if (!semaphore->active) {
		semaphore_unlock(semaphore);
		splx(spl_level);
		return KERN_TERMINATED;
	}

	if (thread != THREAD_NULL) {
		if (semaphore->count < 0) {
			kr = waitq_wakeup64_thread_locked(
					&semaphore->waitq,
					SEMAPHORE_EVENT,
					thread,
					THREAD_AWAKENED,
					WAITQ_UNLOCK);
			/* waitq/semaphore is unlocked */
		} else {
			kr = KERN_NOT_WAITING;
			semaphore_unlock(semaphore);
		}
		splx(spl_level);
		return kr;
	} 

	if (options & SEMAPHORE_SIGNAL_ALL) {
		int old_count = semaphore->count;

		kr = KERN_NOT_WAITING;
		if (old_count < 0) {
			semaphore->count = 0;  /* always reset */
			kr = waitq_wakeup64_all_locked(
					&semaphore->waitq,
					SEMAPHORE_EVENT,
					THREAD_AWAKENED, NULL,
					WAITQ_ALL_PRIORITIES,
					WAITQ_UNLOCK);
			/* waitq / semaphore is unlocked */
		} else {
			if (options & SEMAPHORE_SIGNAL_PREPOST)
				semaphore->count++;
			kr = KERN_SUCCESS;
			semaphore_unlock(semaphore);
		}
		splx(spl_level);
		return kr;
	}
	
	if (semaphore->count < 0) {
		kr = waitq_wakeup64_one_locked(
					&semaphore->waitq,
					SEMAPHORE_EVENT,
					THREAD_AWAKENED, NULL,
					WAITQ_ALL_PRIORITIES,
					WAITQ_KEEP_LOCKED);
		if (kr == KERN_SUCCESS) {
			semaphore_unlock(semaphore);
			splx(spl_level);
			return KERN_SUCCESS;
		} else {
			semaphore->count = 0;  /* all waiters gone */
		}
	}

	if (options & SEMAPHORE_SIGNAL_PREPOST) {
		semaphore->count++;
	}

	semaphore_unlock(semaphore);
	splx(spl_level);
	return KERN_NOT_WAITING;
}