Пример #1
0
   robust_mutex_lock_file()
   {
      permissions p;
      p.set_unrestricted();
      //Remove old lock files of other processes
      remove_old_robust_lock_files();
      //Create path and obtain lock file path for this process
      create_and_get_robust_lock_file_path(fname, get_current_process_id());

      //Now try to open or create the lock file
      fd = create_or_open_file(fname.c_str(), read_write, p);
      //If we can't open or create it, then something unrecoverable has happened
      if(fd == invalid_file()){
         throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: could not open or create file");
      }

      //Now we must take in care a race condition with another process
      //calling "remove_old_robust_lock_files()". No other threads from this
      //process will be creating the lock file because intermodule_singleton
      //guarantees this. So let's loop acquiring the lock and checking if we
      //can't exclusively create the file (if the file is erased by another process
      //then this exclusive open would fail). If the file can't be exclusively created
      //then we have correctly open/create and lock the file. If the file can
      //be exclusively created, then close previous locked file and try again.
      while(1){
         bool acquired;
         if(!try_acquire_file_lock(fd, acquired) || !acquired ){
            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: try_acquire_file_lock");
         }
         //Creating exclusively must fail with already_exists_error
         //to make sure we've locked the file and no one has
         //deleted it between creation and locking
         file_handle_t fd2 = create_new_file(fname.c_str(), read_write, p);
         if(fd2 != invalid_file()){
            close_file(fd);
            fd = fd2;
            continue;
         }
         //If exclusive creation fails with expected error go ahead
         else if(error_info(system_error_code()).get_error_code() == already_exists_error){ //must already exist
            //Leak descriptor to mantain the file locked until the process dies
            break;
         }
         //If exclusive creation fails with unexpected error throw an unrecoverable error
         else{
            close_file(fd);
            throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error");
         }
      }
   }
Пример #2
0
inline int open_or_create_and_lock_file(const char *name)
{
   permissions p;
   p.set_unrestricted();
   while(1){
      int fd = create_or_open_file(name, read_write, p);
      if(fd < 0){
         return fd;
      }
      if(!try_lock_locking_file(fd)){
         close(fd);
         return -1;
      }
      struct stat s;
      if(0 == stat(name, &s)){
         return fd;
      }
      else{
         close(fd);
      }
   }
}
Пример #3
0
inline bool file_wrapper::priv_open_or_create
   (detail::create_enum_t type, 
    const char *filename,
    mode_t mode)
{
   m_filename = filename;

   if(mode != read_only && mode != read_write){
      error_info err(mode_error);
      throw interprocess_exception(err);
   }

   //Open file existing native API to obtain the handle
   switch(type){
      case detail::DoOpen:
         m_handle = open_existing_file(filename, mode);
      break;
      case detail::DoCreate:
         m_handle = create_new_file(filename, mode);
      break;
      case detail::DoOpenOrCreate:
         m_handle = create_or_open_file(filename, mode);
      break;
      default:
         {
            error_info err = other_error;
            throw interprocess_exception(err);
         }
   }

   //Check for error
   if(m_handle == invalid_file()){
      throw interprocess_exception(error_info(system_error_code()));
   }

   m_mode = mode;
   return true;
}
Пример #4
0
inline int open_or_create_and_lock_file(const char *name)
{
   permissions p;
   p.set_unrestricted();
   while(1){
      file_handle_t handle = create_or_open_file(name, read_write, p);
      int fd = _open_osfhandle((intptr_t)handle, _O_TEXT);
      if(fd < 0){
         close_file(handle);
         return fd;
      }
      if(!try_lock_locking_file(fd)){
         _close(fd);
         return -1;
      }
      struct _stat s;
      if(0 == _stat(name, &s)){
         return fd;
      }
      else{
         _close(fd);
      }
   }
}
Пример #5
0
bool
output_sgf (const char *filename)
{
    int current = -1;
    union prop_data_t temp_data;
    int saved = current_node;

    sgf_fd = create_or_open_file (filename);

    if (sgf_fd < 0)
    {
        return false;
    }

    DEBUGF ("outputting to: %s (%d)\n", filename, sgf_fd);

    empty_stack (&parse_stack);

    rb->lseek (sgf_fd, 0, SEEK_SET);
    rb->ftruncate (sgf_fd, 0);

    if (sgf_fd < 0)
    {
        return false;
    }

    if (tree_head < 0)
    {
        close_file (&sgf_fd);
        return false;
    }

    push_int_stack (&parse_stack, tree_head);

    while (pop_int_stack (&parse_stack, &current))
    {
        int var_to_process = 0;
        int temp_prop =
            get_prop_sgf (current, PROP_VARIATION_TO_PROCESS, NULL);

        if (temp_prop >= 0)
        {
            var_to_process = get_prop (temp_prop)->data.number;
        }

        current_node = current;

        if (var_to_process > 0)
        {
            write_char (sgf_fd, ')');
        }

        if (var_to_process == stupid_num_variations ())
        {
            delete_prop_sgf (current, PROP_VARIATION_TO_PROCESS);

            continue;
        }
        else
        {
            write_char (sgf_fd, '\n');
            write_char (sgf_fd, '(');

            /* we need to do more processing on this branchpoint, either
               to do more variations or to output the ')' */
            push_int_stack (&parse_stack, current);

            /* increment the stored variation to process */
            temp_data.number = var_to_process + 1;
            add_or_set_prop_sgf (current,
                                 PROP_VARIATION_TO_PROCESS, temp_data);
        }

        rb->yield ();

        /* now we did the setup for sibling varaitions to be processed so
           do the actual outputting of a game tree branch */

        go_to_variation_sgf (var_to_process);
        output_gametree ();
    }

    current_node = saved;
    close_file (&sgf_fd);
    DEBUGF ("done outputting, file closed\n");
    return true;
}