예제 #1
0
int SerialBase::write(const Buffer& buffer, const event_callback_t& callback, int event) {
    if (serial_tx_active(&_serial)) {
        return -1; // transaction ongoing
    }
    start_write(buffer, 8, callback, event);
    return 0;
}
void block_chain_impl::do_store(block::ptr block, block_store_handler handler)
{
    if (stopped())
        return;

    start_write();

    auto result = database_.blocks.get(block->header.hash());
    if (result)
    {
        const auto height = result.height();
        const auto info = block_info{ block_status::confirmed, height };
        stop_write(handler, error::duplicate, info);
        return;
    }

    const auto detail = std::make_shared<block_detail>(block);
    if (!organizer_.add(detail))
    {
        static constexpr uint64_t height = 0;
        const auto info = block_info{ block_status::orphan, height };
        stop_write(handler, error::duplicate, info);
        return;
    }

    // See replace_chain for block push.
    organizer_.organize();
    stop_write(handler, detail->error(), detail->info());
}
예제 #3
0
파일: httpcli.c 프로젝트: Abioy/kythe
static void on_connected(void *arg, grpc_endpoint *tcp) {
  internal_request *req = arg;

  gpr_log(GPR_DEBUG, "%s", __FUNCTION__);
  if (!tcp) {
    next_address(req);
    return;
  }
  req->ep = tcp;
  if (req->use_ssl) {
    grpc_channel_security_context *ctx = NULL;
    const unsigned char *pem_root_certs = NULL;
    size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
    if (pem_root_certs == NULL || pem_root_certs_size == 0) {
      gpr_log(GPR_ERROR, "Could not get default pem root certs.");
      finish(req, 0);
      return;
    }
    GPR_ASSERT(grpc_httpcli_ssl_channel_security_context_create(
                   pem_root_certs, pem_root_certs_size, req->host, &ctx) ==
               GRPC_SECURITY_OK);
    grpc_setup_secure_transport(&ctx->base, tcp, on_secure_transport_setup_done,
                                req);
    grpc_security_context_unref(&ctx->base);
  } else {
    start_write(req);
  }
}
void AIO_Output_Handler::handle_write_stream
       (const ACE_Asynch_Write_Stream::Result &result) {
  ACE_Message_Block &mblk = result.message_block ();
  if (!result.success ()) {
    mblk.rd_ptr (mblk.base ());
    ungetq (&mblk);
  }
  else {
    can_write_ = handle () == result.handle ();
    if (mblk.length () == 0) {
      mblk.release ();
      if (can_write_) start_write ();
    }
    else if (can_write_) start_write (&mblk);
    else { mblk.rd_ptr (mblk.base ()); ungetq (&mblk); }
  }
}
예제 #5
0
int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event)
{
    if (serial_tx_active(&_serial)) {
        return -1; // transaction ongoing
    }
    start_write((void *)buffer, length, 16, callback, event);
    return 0;
}
예제 #6
0
// Acquires the reader_writer_lock for write.    If the lock is currently held in write
// mode by another context, the writer will block by spinning on a local variable.
// Throws exception improper_lock if the context tries to acquire a
// reader_writer_lock that it already has write ownership of.
void reader_writer_lock::lock() {
    if (is_current_writer()) { // recursive lock attempt
        // we don't support recursive writer locks; throw exception
        tbb::internal::throw_exception(tbb::internal::eid_improper_lock);
    }
    else {
        scoped_lock *a_writer_lock = new scoped_lock();
        (void) start_write(a_writer_lock);
    }
}
예제 #7
0
// Tries to acquire the reader_writer_lock for write.    This function does not block.
// Return Value: True or false, depending on whether the lock is acquired or not.
// If the lock is already held by this acquiring context, try_lock() returns false.
bool reader_writer_lock::try_lock() {
    if (is_current_writer()) { // recursive lock attempt
        return false;
    }
    else {
        scoped_lock *a_writer_lock = new scoped_lock();
        a_writer_lock->status = waiting_nonblocking;
        return start_write(a_writer_lock);
    }
}
예제 #8
0
static void on_handshake_done(void *arg, grpc_endpoint *ep) {
  internal_request *req = arg;

  if (!ep) {
    next_address(req);
    return;
  }

  req->ep = ep;
  start_write(req);
}
예제 #9
0
파일: httpcli.c 프로젝트: sihai/grpc
static void on_secure_transport_setup_done(void *rp,
                                           grpc_security_status status,
                                           grpc_endpoint *secure_endpoint) {
  internal_request *req = rp;
  if (status != GRPC_SECURITY_OK) {
    gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
    finish(req, 0);
  } else {
    req->ep = secure_endpoint;
    start_write(req);
  }
}
예제 #10
0
파일: write.C 프로젝트: fd0/lbfs
  write_obj (file_cache *fe, uint64 size, fattr3 fa, ref<server> srv,
             AUTH *a, write_obj::cb_t cb)
    : cb(cb), srv(srv), fe(fe), fh(fe->fh), fa(fa), auth(a),
      size(size), written(0), outstanding_writes(0),
      callback(false), commit(false)
  {
    assert (fe->afh);

    bytes_wrote = 0;

    if (srv->use_lbfs () && size > LBFS_MIN_BYTES_FOR_CONDWRITE)
      use_lbfs = true;
    else
      use_lbfs = false;

    if (use_lbfs) {
      lbfs_mktmpfile3args arg;
      arg.commit_to = fh;
      tmpfd = server::tmpfd;
      server::tmpfd ++;
      arg.fd = tmpfd;
      arg.obj_attributes.mode.set_set (true);
      *(arg.obj_attributes.mode.val) = fa.mode;
      arg.obj_attributes.uid.set_set (true);
      *(arg.obj_attributes.uid.val) = fa.uid;
      arg.obj_attributes.gid.set_set (true);
      *(arg.obj_attributes.gid.val) = fa.gid;
      arg.obj_attributes.size.set_set (true);
      *(arg.obj_attributes.size.val) = size; // assume this is size of file?
      arg.obj_attributes.atime.set_set (SET_TO_CLIENT_TIME);
      arg.obj_attributes.atime.time->seconds = fa.atime.seconds;
      arg.obj_attributes.atime.time->nseconds = fa.atime.nseconds;
      arg.obj_attributes.mtime.set_set (SET_TO_CLIENT_TIME);
      arg.obj_attributes.mtime.time->seconds = fa.mtime.seconds;
      arg.obj_attributes.mtime.time->nseconds = fa.mtime.nseconds;

      ref<ex_diropres3> res = New refcounted <ex_diropres3>;
      srv->nfsc->call (lbfs_MKTMPFILE, &arg, res,
	               wrap (this, &write_obj::mktmpfile_reply, res),
		       auth);

      chunkv_sz = 0;
    }

    start_write ();
  }
예제 #11
0
void AIO_Output_Handler::open
  (ACE_HANDLE new_handle, ACE_Message_Block &) {
  ACE_SOCK_Stream peer (new_handle);
  int bufsiz = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
  peer.set_option (SOL_SOCKET, SO_SNDBUF,
                   &bufsiz, sizeof bufsiz);

  reader_.open (*this, new_handle, 0, proactor ());
  writer_.open (*this, new_handle, 0, proactor ());

  ACE_Message_Block *mb = 0;
  ACE_NEW (mb, ACE_Message_Block (1));
  reader_.read (*mb, 1);
  ACE_Sig_Action no_sigpipe ((ACE_SignalHandler) SIG_IGN);
  no_sigpipe.register_action (SIGPIPE, 0);
  can_write_ = 1;
  start_write (0);
}
예제 #12
0
파일: UNIO.cpp 프로젝트: martmaiste/UNIO
boolean UNIO::simple_write(const byte *buffer,word address,word length) {
  word wlen;
  while (length>0) {
    wlen=length;
    if (((address&0x0f)+wlen)>16) {
      /* Write would cross a page boundary.  Truncate the write to the
	 page boundary. */
      wlen=16-(address&0x0f);
    }
    if (!enable_write()) return false;
    if (!start_write(buffer,address,wlen)) return false;
    if (!await_write_complete()) return false;
    buffer+=wlen;
    address+=wlen;
    length-=wlen;
  }
  return true;
}
void block_chain_impl::do_import(block::ptr block, block_import_handler handler)
{
    if (stopped())
        return;

    start_write();

    // Disallow import of a duplicate?
    ////auto result = database_.blocks.get(block->header.hash());
    ////if (result)
    ////{
    ////    const auto height = result.height();
    ////    const auto info = block_info{ block_status::confirmed, height };
    ////    stop_write(handler, error::duplicate, info);
    ////    return;
    ////}

    // THIS IS THE DATABASE BLOCK WRITE AND INDEX OPERATION.
    database_.push(*block);
    stop_write(handler, error::success);
}
예제 #14
0
int
main(int argc, char *argv[])
{
  if (argc != 3) {
    printf("Usage: %s <root-dir> <output-device>\n", argv[0]);
    return 1;
  } 

  outfd = open(argv[2],O_WRONLY);
  if (outfd == -1 && errno == ENOENT) {
    outfd = open(argv[2],O_CREAT|O_WRONLY);
  }
  if (outfd == -1)
    err(2, "open output file");

  // Zero out metadata region and reset filehandle
  fzero(outfd, START_OFFSET);
  lseek(outfd, mseek, SEEK_SET);
  
  start_write(argv[1],"");
  lseek(outfd, mseek, SEEK_SET);
  close(outfd);
  return 0;
}
예제 #15
0
파일: level.c 프로젝트: igitur/ffe
static void
print_level_text(struct level *l,uint8_t *buffer)
{
    register uint8_t *text = buffer;

    if(!buffer) return;
    start_write();
    while(*text)
    {
        if(*text == '%' && text[1])
        {
            text++;
            switch(*text)
            {
                case 'g':
                    if(l) writes(l->group_name);
                    break;
                case 'm':
                    if(l) writes(l->element_name);
                    break;
                case '%':
                    writec('%');
                    break;
                default:
                    writec('%');
                    writec(*text);
                    break;
            }
        } else
        {
            writec(*text);
        }
        text++;
    }
    flush_write();
}
예제 #16
0
 writer(mmstore &mms)
     : mms_(mms)
 {
     std::cerr << "writer starts\n";
     start_write();
 }
예제 #17
0
/**
 * Destroys the thread pool.
 *
 * 1. Lock the destruction lock (top priority... don't want to starve here)
 * 2. Change the state
 * 3. Unlock the destruction lock (now, no more tasks can be added because the state
 *	  is checked first, and the threads should know to check the state before dequeuing
 *    anything)
 * 4. Lock the tasks lock, so we're sure all threads are waiting for a signal (or for
 *    the lock) to prevent deadlock (see comments bellow).
 * 5. Broadcast to all threads waiting for tasks: if there's nothing now, there never
 *    will be!
 * 6. Unlock the tasks lock (to allow the threads to do their thing)
 * 7. Wait for all threads to finish
 * 8. Destroy all fields of the pool
 */
void tpDestroy(ThreadPool* tp, int should_wait_for_tasks) {
	
	if (!tp)												// Sanity check
		return;
	
	if (!start_write(tp)) {									// Someone is already writing to pool->state!
		return;												// This should only happen ONCE...
	}
	if (tp->state != ALIVE) {								// Destruction already in progress.
		end_write(tp);										// This can happen if destroy() is called twice fast
		return;
	}
	tp->state = should_wait_for_tasks ? DO_ALL : DO_RUN;	// Enter destroy mode
	PRINT("Destroying the pool! Now allowing state read.\n");
	end_write(tp);											// Allow reading the state

	// Make sure the queue isn't busy.
	// We shouldn't encounter deadlock/livelock here because threads wait for signals, and the only
	// possible source of a signal is here or in tpInsertTask().
	// If we lock this only AFTER we change the/ destruction state, we can create a situation where
	// a thread waits forever for a signal that will never come:
	// - A thread is in it's while loop, the queue is
	//   empty and the pool isn't being destroyed
	//   so it enters the body of the loop. Before it
	//   starts waiting for a signal...
	// - CS-->Main thread
	// - Main thread calls destroy, doesn't wait for
	//   the task_lock and writes the new destruction
	//   state. Then, broadcasts a signal to listening
	//   threads.
	// - CS-->Previous thread
	// - Starts waiting for a signal that will never
	//   come
	// By locking here before broadcasting the destruction, we make sure all threads are waiting for
	// the lock or for the signal! Either way, after the signal, the threads will know what to do and
	// exit the loop.
	pthread_mutex_lock(&tp->task_lock);
	PRINT("Pool destroyed, task lock locked, sending broadcast...\n");
	pthread_cond_broadcast(&tp->queue_not_empty_or_dying);
	PRINT("... done. Unlocking the task lock.\n");
	pthread_mutex_unlock(&tp->task_lock);
	
	// Wait for all threads to exit (this could take a while)
	int i;
	for (i=0; i<tp->N; ++i) {
#if HW3_DEBUG
		PRINT("Waiting for T%2d to finish (tid=%d)...\n", i+1, tp->tids[i]);
#else
		PRINT("Waiting for thread %d to finish...\n", i+1);
#endif
		pthread_join(tp->threads[i], NULL);
#if HW3_DEBUG
		PRINT("T%2d (tid=%d) done.\n", i+1, tp->tids[i]);
#else
		PRINT("Thread %d done.\n", i+1);
#endif
	}
	PRINT("All threads done! Locking the task lock and destroying the task queue...\n");
	
	// Cleanup!
	// Tasks (we can still lock here):
	pthread_mutex_lock(&tp->task_lock);
	while (!osIsQueueEmpty(tp->tasks)) {
		Task* t = (Task*)osDequeue(tp->tasks);
		free(t);
	}
	osDestroyQueue(tp->tasks);
	PRINT("Done. Unlocking the task queue\n");
	pthread_mutex_unlock(&tp->task_lock);
	
	// Locks:
	PRINT("Doing thread pool cleanup...\n");
	pthread_mutex_destroy(&tp->task_lock);
	pthread_mutexattr_destroy(&tp->mutex_type);
	sem_destroy(&tp->r_num_mutex);
	sem_destroy(&tp->w_flag_mutex);
	sem_destroy(&tp->r_entry);
	sem_destroy(&tp->r_try);
	sem_destroy(&tp->state_lock);
	pthread_cond_destroy(&tp->queue_not_empty_or_dying);
	
	// Last cleanup, and out:
#if HW3_DEBUG
	free(tp->tids);
#endif
	free(tp->threads);
	free(tp);
	PRINT("Done destroying thread pool.\n");
	return;
}
예제 #18
0
void
start_write(char *dirname, char *prefix)
{
  struct dirent* dirp;
  DIR* d;
  char *path;
  int infd;
  struct stat st;
  struct fs_hdr *fsh;
  int fseek = START_OFFSET;
  int size;

  if ((d = opendir(dirname)) == NULL)
    err(1, "opendir");

  while ((dirp = readdir(d)) != NULL) {
    switch (dirp->d_type) {
    case DT_REG:
      size = strlen(dirname) + strlen(dirp->d_name) + 2;
      path = malloc(size);
      if(!path)
	err(1, "%s", path);
      snprintf(path, size, "%s/%s", dirname, dirp->d_name);

      //Open the file and write to dst
      infd = open(path, O_RDONLY);
      if (infd < 0)
        err(1, "open");
      free(path);

      if(fstat(infd, &st)!=0)
        err(1, "fstat");

      lseek(outfd, fseek, SEEK_SET);
      size = fcopy(infd, outfd, roundup(st.st_size,SECTOR_SIZE));
      if (size < st.st_size)
	printf("Short file write [%s,%lu,%d]\n",dirp->d_name,st.st_size,size);
      close(infd);

      //Seek to location and Write FS metadata
      char *fname = malloc(512);
      if (!fname) err(1, "malloc");
      snprintf(fname, 512, "%s%s", prefix, dirp->d_name);
      fsh = init_hdr(fname, st.st_size, fseek);
      free(fname);
      lseek(outfd, mseek, SEEK_SET);
      write(outfd, fsh, sizeof(struct fs_hdr));

      //Reset FD pointers
      mseek += SECTOR_SIZE;
      fseek += roundup(size,PAGE_SIZE);

      free(fsh);
      close(infd);
      break;
    case DT_DIR:
      if (!strcmp(dirp->d_name,".") || !strcmp(dirp->d_name,".."))
        break;
      char *subdir, *newprefix;
      subdir=malloc(4096);
      if (!subdir)
        err(1, "malloc");
      newprefix=malloc(512);
      if (!newprefix)
        err(1, "malloc");
      snprintf(subdir, 4096, "%s/%s", dirname, dirp->d_name);
      snprintf(newprefix, 512, "%s%s/", prefix, dirp->d_name);
      start_write(subdir, newprefix);
      free(subdir);
      free(newprefix);
      break;
    default:
      break;
    }
  }
  closedir(d);
}
예제 #19
0
int AIO_Output_Handler::put (ACE_Message_Block *mb,
                             ACE_Time_Value *timeout) {
  if (can_write_) { start_write (mb); return 0; }
  return putq (mb, timeout);
}
int serial_write (
	struct serial_channel*	_chan,
	void*					buf,
	int						len)
{
	struct serial_win32*	chan = (struct serial_win32*)_chan;

	for (;;)
	{
		switch (chan->txState)
		{
		case TXSTATE_NONE:
			if (   chan->txBuf == (char*)buf
				&& chan->txSentLen == chan->txBufLen)
			{
				/* The caller has tried to send this buffer before, but
				 * this function returned -1 and claimed to reject it
				 * before.  In reality, this function has finished writing
				 * the buffer out using overlapped IO, and the caller is
				 * calling because the final overlapped IO event has
				 * completed.  Clear out txbuf and return back the total
				 * number of bytes sent.
				 */
				int			actSent = chan->txSentLen;

				chan->txBuf = NULL;
				chan->txBufLen = 0;
				chan->txSentLen = 0;

				SetEvent(chan->eTxDone);
				return actSent;

			} else if (NULL == chan->txBuf)
			{
				/* The output buffer doesn't exist, so no IO is currently
				 * in progress.  Accept the caller's buffer and try to get
				 * the IO started.
				 */
				if (len > 0 && buf != NULL)
				{
					chan->txBuf = (char*)buf;
					chan->txBufLen = len;
					chan->txSentLen = 0;

					/* If the first write goes into a pending state, return
					 * -1 to the caller.  The caller will think no data was
					 * transmitted yet (due to buffers being full) but really
					 * the data is already on its way.
					 */
					if ( ! start_write(chan))
					{
						return -1;
					}

					/* If we fall through, the write completed, but there may
					 * still be data in the output buffer left for
					 * transmission.  Loop and try to start another IO event.
					 */

				} else
				{
					/* No IO to perform.  Manually set the eTxDone event so
					 * the caller will get signaled and know its safe to
					 * provide another buffer of data to the write call.
					 */
					SetEvent(chan->eTxDone);
					return 0;
				}

			} else if (   chan->txBuf != NULL
					   && chan->txSentLen < chan->txBufLen)
			{
				/* The tx buffer has not been full transmitted, and no IO
				 * opertion is pending.  Start a new write.  If it goes into
				 * pending state, return to the caller.
				 */
				if ( ! start_write(chan))
				{
					return -1;
				}
			}
			break;

		case TXSTATE_WRITE:
			/* The serial port write may have just finished.  If it is
			 * really done, run the loop again to try and start a new
			 * write, or to discover the buffer is complete and either
			 * start the new buffer supplied by the user, or make eTxDone
			 * manually set.
			 */
			if ( ! finish_write(chan))
			{
				return -1;
			}
			break;
		}
	}
}