result_t Socket::copyTo(Stream_base *stm, int64_t bytes, int64_t &retVal, exlib::AsyncEvent *ac) { if (m_sock == INVALID_SOCKET) return CHECK_ERROR(CALL_E_INVALID_CALL); return copyStream(this, stm, bytes, retVal, ac); }
result_t File::copyTo(Stream_base *stm, int64_t bytes, int64_t &retVal, AsyncEvent *ac) { if (m_fd == -1) return CHECK_ERROR(CALL_E_INVALID_CALL); return copyStream(this, stm, bytes, retVal, ac); }
SkStream* FontConfigTypeface::onOpenStream(int* ttcIndex) const { SkStream* stream = this->getLocalStream(); if (stream) { // should have been provided by CreateFromStream() *ttcIndex = 0; SkAutoTUnref<SkStream> dupStream(stream->duplicate()); if (dupStream) { return dupStream.detach(); } // TODO: update interface use, remove the following code in this block. size_t length = stream->getLength(); const void* memory = stream->getMemoryBase(); if (NULL != memory) { return new SkMemoryStream(memory, length, true); } SkAutoTMalloc<uint8_t> allocMemory(length); stream->rewind(); if (length == stream->read(allocMemory.get(), length)) { SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream()); copyStream->setMemoryOwned(allocMemory.detach(), length); return copyStream.detach(); } stream->rewind(); stream->ref(); } else { SkAutoTUnref<SkFontConfigInterface> fci(RefFCI()); if (NULL == fci.get()) { return NULL; } stream = fci->openStream(this->getIdentity()); *ttcIndex = this->getIdentity().fTTCIndex; } return stream; }
result_t BufferedStream::copyTo(Stream_base *stm, int64_t bytes, int64_t &retVal, AsyncEvent *ac) { return copyStream(this, stm, bytes, retVal, ac); }
result_t SslSocket::copyTo(Stream_base *stm, int64_t bytes, int64_t &retVal, exlib::AsyncEvent *ac) { return copyStream(this, stm, bytes, retVal, ac); }
result_t MemoryStream::CloneStream::copyTo(Stream_base *stm, int64_t bytes, int64_t &retVal, AsyncEvent *ac) { return copyStream(this, stm, bytes, retVal, ac); }
/* * Enter loop to copy all files in stream. This function waits for * and services copy request from the scheduler. */ void CopyFiles(void) { pthread_t tid; int rval; struct timespec timeout; ASSERT(Instance != NULL); (void) sprintf(fullpath, "%s/%s/rm%d/%s", SAM_VARIABLE_PATH, STAGER_DIRNAME, Instance->ci_rmfn, COPY_FILE_FILENAME); SamStrdup(copyRequestPath, fullpath); /* Initialize structure for communcation between io threads. */ initIoThread(); /* Start io threads */ rval = pthread_create(&tid, NULL, ArchiveRead, NULL); if (rval != 0) { LibFatal(pthread_create, "ArchiveRead"); } rval = pthread_create(&tid, NULL, DoubleBuffer, NULL); if (rval != 0) { LibFatal(pthread_create, "DoubleBuffer"); } for (;;) { timeout.tv_sec = time(NULL) + COPY_INSTANCE_TIMEOUT_SECS; timeout.tv_nsec = 0; PthreadMutexLock(&Instance->ci_requestMutex); Instance->ci_busy = B_FALSE; Instance->ci_idletime = time(NULL); /* * Wait for a request from daemon to stage files. */ while (Instance->ci_first == NULL && !IF_SHUTDOWN(Instance)) { pid_t ppid; /* * Exit if parent stager daemon died * or reconfig requested. */ if (((ppid = getppid()) == 1) || (CopyInstanceList->cl_reconfig == B_TRUE)) { SetErrno = 0; /* set for trace */ Trace(TR_ERR, "Detected stager daemon %s", ppid == 1 ? "exit" : "reconfig"); SET_FLAG(Instance->ci_flags, CI_shutdown); break; } rval = pthread_cond_timedwait(&Instance->ci_request, &Instance->ci_requestMutex, &timeout); if (rval == ETIMEDOUT) { /* * Wait timed out. If no open disk cache files * set shutdown flag so we exit loop. If open * files, reset timeout value and wait for work. */ if (NumOpenFiles <= 0 && Instance->ci_first == NULL) { SET_FLAG(Instance->ci_flags, CI_shutdown); /* * Set instance to 'busy' while this * process is exiting and the stager * daemon detects that it exited. */ Instance->ci_busy = B_TRUE; } else { timeout.tv_sec = time(NULL) + COPY_INSTANCE_TIMEOUT_SECS; timeout.tv_nsec = 0; } } } /* If shutdown requested exit loop. */ if (IF_SHUTDOWN(Instance)) { Trace(TR_PROC, "Shutdown instance: 0x%x first: 0x%x", (int)Instance, (int)Instance->ci_first); PthreadMutexUnlock(&Instance->ci_requestMutex); break; } /* * Received a copy request from stager daemon. Initialize * ourself and notify daemon that we got it. */ Request = (CopyRequestInfo_t *)MapInFile(copyRequestPath, O_RDWR, NULL); if (Request == NULL) { Trace(TR_ERR, "Cannot map in file %s", copyRequestPath); if (errno == EMFILE) { /* * Open max reached. This should not happen. * Stream will be requeued by parent. */ PthreadMutexUnlock(&Instance->ci_requestMutex); LibFatal(MapInFile, "EMFILE"); } continue; } /* Grab next request from the queue. */ Instance->ci_first = Request->cr_next; if (Instance->ci_first == NULL) { Instance->ci_last = NULL; } Trace(TR_QUEUE, "Got request: '%s.%d' 0x%x", Request->cr_vsn, Request->cr_seqnum, (int)Request); /* Generate path name and map in the stream. */ (void) sprintf(fullpath, "%s/%s.%d", SharedInfo->si_streamsDir, Request->cr_vsn, Request->cr_seqnum); Stream = (StreamInfo_t *)MapInFile(fullpath, O_RDWR, NULL); if (Stream == NULL) { Trace(TR_ERR, "Cannot map in file %s", fullpath); if (errno == EMFILE) { /* * Open max reached. This should not happen. * Stream will be requeued by parent. */ PthreadMutexUnlock(&Instance->ci_requestMutex); LibFatal(MapInFile, "EMFILE"); } continue; } Instance->ci_vsnLib = Stream->vi.lib; Instance->ci_busy = B_TRUE; /* Notify daemon we got the copy request. */ Request->cr_gotItFlag = B_TRUE; PthreadCondSignal(&Request->cr_gotIt); PthreadMutexUnlock(&Instance->ci_requestMutex); /* Stage all files in stream. */ if (STREAM_IS_AVAILABLE()) { copyStream(); } else { /* * Resources for the stream are not available. * Close open file descriptors. */ closeStream(); } } }