Exemple #1
0
void output(MotifSearch* ms) {
	string tmpstr(outfile);
	string outstr(outfile);
	string lockstr(outfile);
	tmpstr.append(".tmp.ms");
	outstr.append(".ms");
	lockstr.append(".lock");
	ofstream tmp(tmpstr.c_str(), ios::trunc);
	ms->full_output(tmp);
	tmp.close();
	struct flock fl;
	int fd;
	fl.l_type   = F_WRLCK;
	fl.l_whence = SEEK_SET;
	fl.l_start  = 0;
	fl.l_len    = 0;
	fl.l_pid    = getpid();
	fd = open(lockstr.c_str(), O_WRONLY | O_CREAT, 0644);
	while(fcntl(fd, F_SETLK, &fl) == -1) {
		cerr << "Waiting for lock release on archive file...\n";
		sleep(10);
	}
	rename(tmpstr.c_str(), outstr.c_str());
	cerr << "Archive output completed.\n";
	fl.l_type = F_UNLCK;
	fcntl(fd, F_SETLK, &fl);
	close(fd);
}
// Remove our mail-spool-file lock (n.b. we should only try this if
// we're the ones who made the lock in the first place!)
PRBool YieldSpoolLock(const char *spoolnameStr)
{
    LOG(("YieldSpoolLock(%s)", spoolnameStr));

    nsCAutoString lockstr(spoolnameStr);
    lockstr.Append(".lock");

    nsresult rv;

    // Create nsILocalFile for the spool.lock file
    nsCOMPtr<nsILocalFile> locklocfile;
    rv = NS_NewNativeLocalFile(lockstr, PR_TRUE, getter_AddRefs(locklocfile));
    if (NS_FAILED(rv))
        return PR_FALSE;

    // Check if the lock file exists
    PRBool exists;
    rv = locklocfile->Exists(&exists);
    if (NS_FAILED(rv))
        return PR_FALSE;

    // Delete the file if it exists
    if (exists) {
        rv = locklocfile->Remove(PR_FALSE /* non-recursive */);
        if (NS_FAILED(rv))
            return PR_FALSE;
    }

    LOG(("YieldSpoolLock was successful."));

    // Success.
    return PR_TRUE;
}
Exemple #3
0
// Remove our mail-spool-file lock (n.b. we should only try this if
// we're the ones who made the lock in the first place!)
bool YieldSpoolLock(const char *aSpoolName, bool aUsingLockFile)
{
  LOG(("YieldSpoolLock(%s)", aSpoolName));

  if (!aUsingLockFile) {
    nsCOMPtr<nsILocalFile> spoolFile;
    nsresult rv = NS_NewNativeLocalFile(nsDependentCString(aSpoolName),
                                        true,
                                        getter_AddRefs(spoolFile));
    NS_ENSURE_SUCCESS(rv, false);

    PRFileDesc *fd;
    rv = spoolFile->OpenNSPRFileDesc(PR_RDWR, 0, &fd);
    NS_ENSURE_SUCCESS(rv, false);

    bool unlockSucceeded = PR_UnlockFile(fd) == PR_SUCCESS;
    PR_Close(fd);
    if (unlockSucceeded)
      LOG(("YieldSpoolLock was successful."));
    return unlockSucceeded;
  }

  nsCAutoString lockstr(aSpoolName);
  lockstr.Append(".lock");

  nsresult rv;

  // Create nsILocalFile for the spool.lock file
  nsCOMPtr<nsILocalFile> locklocfile;
  rv = NS_NewNativeLocalFile(lockstr, true, getter_AddRefs(locklocfile));
  if (NS_FAILED(rv))
    return false;

  // Check if the lock file exists
  bool exists;
  rv = locklocfile->Exists(&exists);
  if (NS_FAILED(rv))
    return false;

  // Delete the file if it exists
  if (exists) {
    rv = locklocfile->Remove(false /* non-recursive */);
    if (NS_FAILED(rv))
      return false;
  }

  LOG(("YieldSpoolLock was successful."));

  // Success.
  return true;
}
Exemple #4
0
bool ObtainSpoolLock(const char *aSpoolName,
                       int aSeconds /* number of seconds to retry */,
                       bool *aUsingLockFile)
{
  NS_ENSURE_TRUE(aUsingLockFile, false);

  /*
   * Locking procedures:
   * If the directory is not writable, we want to use the appropriate system
   * utilites to lock the file.
   * If the directory is writable, we want to go through the create-and-link
   * locking procedures to make it atomic for certain networked file systems.
   * This involves creating a .mozlock file and attempting to hard-link it to
   * the customary .lock file.
   */
  nsCOMPtr<nsILocalFile> spoolFile;
  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(aSpoolName),
                                      true,
                                      getter_AddRefs(spoolFile));
  NS_ENSURE_SUCCESS(rv, false);

  nsCOMPtr<nsIFile> directory;
  rv = spoolFile->GetParent(getter_AddRefs(directory));
  NS_ENSURE_SUCCESS(rv, false);

  rv = directory->IsWritable(aUsingLockFile);
  NS_ENSURE_SUCCESS(rv, false);

  if (!*aUsingLockFile) {
    LOG(("Attempting to use kernel file lock"));
    PRFileDesc *fd;
    rv = spoolFile->OpenNSPRFileDesc(PR_RDWR, 0, &fd);
    NS_ENSURE_SUCCESS(rv, false);
    PRStatus lock_result;
    int retry_count = 0;

    do {
      lock_result = PR_TLockFile(fd);
  
      retry_count++;
      LOG(("Attempt %d of %d to lock file", retry_count, aSeconds));
      if (aSeconds > 0 && lock_result == PR_FAILURE) {
        // pause 1sec, waiting for .lock to go away
        PRIntervalTime sleepTime = 1000; // 1 second
        PR_Sleep(sleepTime);
      }
    } while (lock_result == PR_FAILURE && retry_count < aSeconds);
    LOG(("Lock result: %d", lock_result));
    PR_Close(fd);
    return lock_result == PR_SUCCESS;
  }
  // How to lock using files:
  // step 1: create SPOOLNAME.mozlock
  //        1a: can remove it if it already exists (probably crash-droppings)
  // step 2: hard-link SPOOLNAME.mozlock to SPOOLNAME.lock for NFS atomicity
  //        2a: if SPOOLNAME.lock is >60sec old then nuke it from orbit
  //        2b: repeat step 2 until retry-count expired or hard-link succeeds
  // step 3: remove SPOOLNAME.mozlock
  // step 4: If step 2 hard-link failed, fail hard; we do not hold the lock
  // DONE.
  //
  // (step 2a not yet implemented)


  nsCAutoString mozlockstr(aSpoolName);
  mozlockstr.Append(".mozlock");
  nsCAutoString lockstr(aSpoolName);
  lockstr.Append(".lock");

  // Create nsILocalFile for the spool.mozlock file
  nsCOMPtr<nsILocalFile> tmplocfile;
  rv = NS_NewNativeLocalFile(mozlockstr, true, getter_AddRefs(tmplocfile));
  if (NS_FAILED(rv))
    return false;
  // THOUGHT: hmm, perhaps use MakeUnique to generate us a unique mozlock?
  // ... perhaps not, MakeUnique implementation looks racey -- use mktemp()?

  // step 1: create SPOOLNAME.mozlock
  rv = tmplocfile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
  if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
    // can't create our .mozlock file... game over already
    LOG(("Failed to create file %s\n", mozlockstr.get()));
    return false;
  }

  // step 2: hard-link .mozlock file to .lock file (this wackiness
  //         is necessary for non-racey locking on NFS-mounted spool dirs)
  // n.b. XPCOM utilities don't support hard-linking yet, so we
  // skip out to <unistd.h> and the POSIX interface for link()
  int link_result = 0;
  int retry_count = 0;

  do {
    link_result = link(mozlockstr.get(),lockstr.get());

    retry_count++;
    LOG(("Attempt %d of %d to create lock file", retry_count, aSeconds));

    if (aSeconds > 0 && link_result == -1) {
      // pause 1sec, waiting for .lock to go away
      PRIntervalTime sleepTime = 1000; // 1 second
      PR_Sleep(sleepTime);
    }
  } while (link_result == -1 && retry_count < aSeconds);
  LOG(("Link result: %d", link_result));

  // step 3: remove .mozlock file, in any case
  rv = tmplocfile->Remove(false /* non-recursive */);
  if (NS_FAILED(rv)) {
    // Could not delete our .mozlock file... very unusual, but
    // not fatal.
    LOG(("Unable to delete %s", mozlockstr.get()));
  }

  // step 4: now we know whether we succeeded or failed
  return link_result == 0;
}
Exemple #5
0
int main(int argc, char *argv[]) {
	set_new_handler(alloc_error);

	if(argc < 6) {
		print_usage(cout);
		exit(0);
	}
	
	string seqfile;                       // file with sequences
	string exprfile;                      // file with expression data
	string subsetfile;                    // file with subset of sequence names to search
	string scorefile;                     // file with scores

	if(! GetArg2(argc, argv, "-s", seqfile)) {
		cerr << "Please specify sequence file\n\n";
		print_usage(cout);
		exit(0);
	}
	if(! GetArg2(argc, argv, "-o", outfile)) {
		cerr << "Please specify output file\n\n";
		print_usage(cout);
		exit(0);
	}
	
	int search_type = UNDEFINED;
	if(GetArg2(argc, argv, "-ex", exprfile)) {
		search_type = EXPRESSION;
	}
	if(GetArg2(argc, argv, "-su", subsetfile)) {
		search_type = SUBSET;
	}
	if(GetArg2(argc, argv, "-sc", scorefile)) {
		search_type = SCORE;
	}
	if(search_type == UNDEFINED) {
		cerr << "Please specify either an expression data file, a file with a subset of sequence names, or a file with sequence scores.\n\n";
		print_usage(cout);
		exit(0);
	}

	// Decide mode of running
	archive = false;
	if(! GetArg2(argc, argv, "-worker", worker)) {
		worker = -1;
		archive = true;
	}
	
	// Read parameters
	vector<string> seqs;
	cerr << "Reading sequence data from '" << seqfile << "'... ";
	get_fasta_fast(seqfile.c_str(), seqs, seq_nameset);
	cerr << "done.\n";
	ngenes = seq_nameset.size();
	
	npoints = 0;
	if(search_type == EXPRESSION) {
		cerr << "Reading expression data from '" << exprfile << "'... ";
		get_expr(exprfile.c_str(), expr, data_nameset);
		cerr << "done.\n";
		npoints = expr[0].size();
		nsubset = 0;
	} else if(search_type == SUBSET) {
		cerr << "Reading subset of sequences to search from '" << subsetfile << "'... ";
		get_list(subsetfile.c_str(), subset);
		cerr << "done.\n";
		npoints = 0;
		for(int i = 0; i < ngenes; i++) {
			vector<float> row(0);
			expr.push_back(row);
		}
		nsubset = subset.size();
		sort(subset.begin(), subset.end());
	} else if(search_type == SCORE) {
		cerr << "Reading sequence scores from '" << scorefile << "'... ";
		get_scores(scorefile.c_str(), scores, data_nameset);
		cerr << "done.\n";
		npoints = 1;
		nsubset = 0;
	}

	vector<vector <float> > newexpr;
	vector<float> newscores;
	if(search_type == EXPRESSION) {
		order_data_expr(newexpr);
	}
	if(search_type == SCORE) {
		order_data_scores(newscores);
	}

	if(search_type == EXPRESSION) {
		cerr << "Successfully read input files -- dataset size is " << ngenes << " sequences X " << npoints << " timepoints\n";
	} else if(search_type == SUBSET) {
		cerr << "Successfully read input files -- dataset size is " << ngenes << " sequences, with " << nsubset << " to be searched\n";
	} else if(search_type == SCORE) {
		cerr << "Successfully read input files -- dataset size is " << ngenes << " scored sequences\n";
	}

	cerr << "Setting up MotifSearch... ";
	if(! GetArg2(argc, argv, "-numcols", ncol)) ncol = 10;
	if(! GetArg2(argc, argv, "-order", order)) order = 0;
	if(! GetArg2(argc, argv, "-simcut", simcut)) simcut = 0.8;
	if(! GetArg2(argc, argv, "-maxm", maxm)) maxm = 20;
	MotifSearch* ms;
	if(search_type == EXPRESSION) {
		ms = new MotifSearchExpr(seq_nameset, seqs, ncol, order, simcut, maxm, newexpr, npoints);
	} else if(search_type == SCORE) {
		ms = new MotifSearchScore(seq_nameset, seqs, ncol, order, simcut, maxm, newscores);
	} else {
		ms = new MotifSearchSubset(seq_nameset, seqs, ncol, order, simcut, maxm, subset);
	}
	ms->modify_params(argc, argv);
	ms->set_final_params();
	ms->ace_initialize();
	cerr << "done.\n";
	cerr << "Random seed: " << ms->get_params().seed << '\n';

	if(archive) {
		cerr << "Running in archive mode...\n";
		string archinstr(outfile);
		archinstr.append(".ms");
		ifstream archin(archinstr.c_str());
		if(archin) {
			cerr << "Refreshing from existing archive file " << archinstr << "... ";
			ms->get_archive().read(archin);
			cerr << "done.\n";
		}
		while(true) {
			int found = read_motifs(ms);
			if(found > 0) output(ms);
			if(found < 50) sleep(10);
		}
	} else {
		cerr << "Running as worker " << worker << "...\n";
		int nruns = ms->positions_in_search_space()/(ms->get_params().expect * ncol);
		nruns *= ms->get_params().oversample;
		nruns /= ms->get_params().undersample;
		cerr << "Restarts planned: " << nruns << '\n';
		string archinstr(outfile);
		archinstr.append(".ms");
		string lockstr(outfile);
		lockstr.append(".lock");
		for(int j = 1; j <= nruns; j++) {
			if(j == 1 || j % 50 == 0 || search_type == SUBSET) {
				struct flock fl;
				int fd;
				fl.l_type   = F_RDLCK;
				fl.l_whence = SEEK_SET;
				fl.l_start  = 0;
				fl.l_len    = 0;
				fl.l_pid    = getpid();
				fd = open(lockstr.c_str(), O_RDONLY);
				if(fd == -1) {
					if(errno != ENOENT)
						cerr << "\t\tUnable to read lock file, error was " << strerror(errno) << "\n";
				} else {
					while(fcntl(fd, F_SETLK, &fl) == -1) {
						cerr << "\t\tWaiting for lock release on archive file... \n";
						sleep(10);
					}
					ifstream archin(archinstr.c_str());
					if(archin) {
						cerr << "\t\tRefreshing archive from " << archinstr << "...";
						ms->get_archive().clear();
						ms->get_archive().read(archin);
						archin.close();
						cerr << "done.\n";
					}
					fl.l_type = F_UNLCK;
					fcntl(fd, F_SETLK, &fl);
					close(fd);
					cerr << "\t\tArchive now has " << ms->get_archive().nmots() << " motifs\n";
				}
			}
			cerr << "\t\tSearch restart #" << j << "/" << nruns << "\n";
			ms->search_for_motif(worker, j, outfile);
		}
	}
	delete ms;
	return 0;
}
PRBool ObtainSpoolLock(const char *spoolnameStr,
                       int seconds /* number of seconds to retry */)
{
    // How to lock:
    // step 1: create SPOOLNAME.mozlock
    //        1a: can remove it if it already exists (probably crash-droppings)
    // step 2: hard-link SPOOLNAME.mozlock to SPOOLNAME.lock for NFS atomicity
    //        2a: if SPOOLNAME.lock is >60sec old then nuke it from orbit
    //        2b: repeat step 2 until retry-count expired or hard-link succeeds
    // step 3: remove SPOOLNAME.mozlock
    // step 4: If step 2 hard-link failed, fail hard; we do not hold the lock
    // DONE.
    //
    // (step 2a not yet implemented)
    
    nsCAutoString mozlockstr(spoolnameStr);
    mozlockstr.Append(".mozlock");
    nsCAutoString lockstr(spoolnameStr);
    lockstr.Append(".lock");

    nsresult rv;

    // Create nsILocalFile for the spool.mozlock file
    nsCOMPtr<nsILocalFile> tmplocfile;
    rv = NS_NewNativeLocalFile(mozlockstr, PR_TRUE, getter_AddRefs(tmplocfile));
    if (NS_FAILED(rv))
        return PR_FALSE;
    // THOUGHT: hmm, perhaps use MakeUnique to generate us a unique mozlock?
    // ... perhaps not, MakeUnique implementation looks racey -- use mktemp()?

    // step 1: create SPOOLNAME.mozlock
    rv = tmplocfile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
    if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
        // can't create our .mozlock file... game over already
        LOG(("Failed to create file %s\n", mozlockstr.get()));
        return PR_FALSE;
    }

    // step 2: hard-link .mozlock file to .lock file (this wackiness
    //         is necessary for non-racey locking on NFS-mounted spool dirs)
    // n.b. XPCOM utilities don't support hard-linking yet, so we
    // skip out to <unistd.h> and the POSIX interface for link()
    int link_result = 0;
    int retry_count = 0;
    
    do {
        link_result = link(mozlockstr.get(),lockstr.get());

        retry_count++;
        LOG(("Attempt %d of %d to create lock file", retry_count, seconds));

        if (seconds > 0 && link_result == -1) {
            // pause 1sec, waiting for .lock to go away
            PRIntervalTime sleepTime = 1000; // 1 second
            PR_Sleep(sleepTime);
        }
    } while (link_result == -1 && retry_count < seconds);
    LOG(("Link result: %d", link_result));

    // step 3: remove .mozlock file, in any case
    rv = tmplocfile->Remove(PR_FALSE /* non-recursive */);
    if (NS_FAILED(rv)) {
        // Could not delete our .mozlock file... very unusual, but
        // not fatal.
        LOG(("Unable to delete %s", mozlockstr.get()));
    }

    // step 4: now we know whether we succeeded or failed
    if (link_result == 0)
        return PR_TRUE; // got the lock.
    else
        return PR_FALSE; // didn't.  :(
}