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()); }
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); } } }
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; }
// 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); } }
// 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); } }
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); }
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); } }
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 (); }
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); }
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); }
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; }
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(); }
writer(mmstore &mms) : mms_(mms) { std::cerr << "writer starts\n"; start_write(); }
/** * 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; }
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); }
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; } } }