void GetURLHandler::ReadBody() { // Note that you specifically want an "optional" callback here. This will // allow ReadBody() to return synchronously, ignoring your completion // callback, if data is available. For fast connections and large files, // reading as fast as we can will make a large performance difference // However, in the case of a synchronous return, we need to be sure to run // the callback we created since the loader won't do anything with it. pp::CompletionCallback cc = cc_factory_.NewOptionalCallback(&GetURLHandler::OnRead); int32_t result = PP_OK; do { result = url_loader_.ReadResponseBody(buffer_, sizeof(buffer_), cc); // Handle streaming data directly. Note that we *don't* want to call // OnRead here, since in the case of result > 0 it will schedule // another call to this function. If the network is very fast, we could // end up with a deeply recursive stack. if (result > 0) { AppendDataBytes(buffer_, result); } } while (result > 0); if (result != PP_OK_COMPLETIONPENDING) { // Either we reached the end of the stream (result == PP_OK) or there was // an error. We want OnRead to get called no matter what to handle // that case, whether the error is synchronous or asynchronous. If the // result code *is* COMPLETIONPENDING, our callback will be called // asynchronously. cc.Run(result); } }
/** * Thread function to read Vertica data per Vertica socket connection * - Reads metadata and raw data bytes as received from Vertica * - Appends data bytes to Buffer * **/ void DataLoader::ReadFromVertica(int32_t connection_fd) { struct Metadata metadata; int n = recv(connection_fd, &metadata, sizeof(metadata), 0); if(n == 0) LOG_ERROR("No Metadata received from Vertica"); else if (n<0) LOG_ERROR("Error in receiving Metadata from Vertica"); uint64_t data_size = metadata.size; uint32_t nrows = metadata.nrows; bool is_eof = metadata.isEOF; if(!is_eof) { ostringstream shm_file; shm_file.str(""); char data_buffer[data_size]; //size_t b_read = atomicio(read, connection_fd, data_buffer, data_size); //data_buffer[b_read]='\0'; while((errno = 0, (n = recv(connection_fd, data_buffer, sizeof(data_buffer), 0))>0) || errno == EINTR) { if(n == 0) { LOG_ERROR("No data bytes received from Vertica"); break; } else if (n<0){ LOG_ERROR("Error in receiving Metadata from Vertica"); break; } else { data_buffer[n]='\0'; shm_file << data_buffer; } } AppendDataBytes(shm_file.str().c_str(), data_size, nrows); } else { unique_lock<recursive_mutex> lock(metadata_mutex_); if(vnode_EOFs.find(metadata.vNode_name) == vnode_EOFs.end()) { vnode_EOFs[metadata.vNode_name] = 1; } else { ++vnode_EOFs[metadata.vNode_name]; } lock.unlock(); } close(connection_fd); }
void GetURLHandler::OnRead(int32_t result) { if (result == PP_OK) { // Streaming the file is complete. status = STATUS_COMPLETED; instance_->HandleMessage("package_finished"); instance_->HandleMessage(0); printf("completed!\n"); } else if (result > 0) { // The URLLoader just filled "result" number of bytes into our buffer. // Save them and perform another read. AppendDataBytes(buffer_, result); ReadBody(); } else { // A read error occurred. status = STATUS_ERROR; ERR_FAIL_COND(result < 0); } }
void URLLoaderHandler::OnRead(int32_t result) { if (result == PP_OK) { // Streaming the file is complete, delete the read buffer since it is // no longer needed. delete[] buffer_; buffer_ = NULL; ReportResultAndDie(url_, url_response_body_, true); } else if (result > 0) { // The URLLoader just filled "result" number of bytes into our buffer. // Save them and perform another read. AppendDataBytes(buffer_, result); ReadBody(); } else { // A read error occurred. ReportResultAndDie( url_, "pp::URLLoader::ReadResponseBody() result<0", false); } }