mt_mutex (mutex) mt_throws Result LinePipe::openPipeSession () { assert (!pipe_session); pipe_session = grab (new (std::nothrow) PipeSession (NULL /* embed_container */)); pipe_session->weak_line_pipe = this; bool opened = false; if (!pipe_session->line_file->open (filename->mem(), 0 /* open_flags */, FileAccessMode::ReadOnly)) { goto _close; } opened = true; pipe_session->line_receiver->init (pipe_session->line_file, deferred_processor); pipe_session->line_server->init (pipe_session->line_receiver, CbDesc<LineServer::Frontend> (&line_frontend, pipe_session, pipe_session), max_line_len); pipe_session->pollable_key = poll_group->addPollable (pipe_session->line_file->getPollable()); if (!pipe_session->pollable_key) goto _close; pipe_session->line_receiver->start (); return Result::Success; _close: { StRef<String> const error_str = exc->toString(); if (!prv_error_str || !equal (prv_error_str->mem(), error_str ? error_str->mem() : ConstMemory())) { prv_error_str = st_grab (new (std::nothrow) String (error_str ? error_str->mem() : ConstMemory())); logW_ (_func, "could not open pipe\"", filename, "\": ", error_str); } } ExceptionBuffer * const exc_buf = exc_swap_nounref (); if (opened) { if (!pipe_session->line_file->close (false /* flush_data */)) logE_ (_func, "file.close() failed: ", exc->toString()); } pipe_session = NULL; if (timers) { reopen_timer = timers->addTimer_microseconds ( CbDesc<Timers::TimerCallback> (reopenTimerTick, this, this), reopen_timeout_millisec * 1000, false /* periodical */); } exc_set_noref (exc_buf); return Result::Failure; }
mt_mutex (mutex) void Recorder::doStartItem () { logD_ (_func_); if (!recording_now) { logD_ (_func, "!recording_now"); return; } assert (cur_channel_name); Ref<VideoStream> video_stream; if (Ref<StreamManager> const stream_manager = weak_stream_manager.getRef ()) { video_stream = stream_manager->getStream (cur_channel_name->mem()); } else { logD_ (_this_func, "stream_manager gone"); return; } if (!video_stream) { logW_ (_func, "stream \"", cur_channel_name->mem(), "\" not found"); return; } weak_cur_video_stream = video_stream; recorder->setVideoStream (video_stream); { Format fmt; fmt.num_base = 10; fmt.min_digits = 2; LibMary_ThreadLocal * const tlocal = libMary_getThreadLocal(); StRef<String> const filename = makeString ( fmt, filename_prefix->mem(), filename_prefix->mem().len() > 0 ? "_" : "", tlocal->localtime.tm_year + 1900, "-", tlocal->localtime.tm_mon + 1, "-", tlocal->localtime.tm_mday, "_", tlocal->localtime.tm_hour, "-", tlocal->localtime.tm_min, "-", tlocal->localtime.tm_sec, ".flv"); logD_ (_func, "calling recorder.start(), filename: ", filename->mem()); recorder->start (filename->mem()); } }
Result AmfDecoder::doDecodeStringData_AMF3 (Memory const mem, Size * const ret_len, Size * const ret_full_len) { Uint32 length; if (!decodeU29 (&length)) return Result::Failure; bool const is_ref = !(length & 1); length >>= 1; Size tocopy; Size string_len; if (is_ref) { StRef<String> const str = getString (length /* index */); if (!str) { logD_ (_func, "unresolved string reference"); return Result::Failure; } string_len = str->len(); tocopy = (mem.len() > string_len ? string_len : mem.len()); memcpy (mem.mem(), str->mem().mem(), tocopy); } else { string_len = length; if (msg_len - cur_offset < string_len) { logE_ (_func, "message is too short"); return Result::Failure; } StRef<String> const str = st_grab (new String (string_len)); array->get (cur_offset, str->mem()); string_table.append (str); tocopy = (mem.len() > string_len ? string_len : mem.len()); array->get (cur_offset, mem.region (0, tocopy)); cur_offset += string_len; } if (ret_len) *ret_len = tocopy; if (ret_full_len) *ret_full_len = string_len; return Result::Success; }
Result FileNameToUnixTimeStamp::Convert(const StRef<String> & fileName, /*output*/ Time & timeOfRecord) { if(fileName == NULL || !fileName->len()) return Result::Failure; Result res = Result::Success; std::string stdStr(fileName->cstr()); std::string delimiter1 = "_"; std::string delimiter2 = "."; size_t pos = 0; std::string token; pos = stdStr.rfind(delimiter1); if(pos != std::string::npos) { token = stdStr.substr(0, pos); stdStr.erase(0, pos + delimiter1.length()); pos = stdStr.rfind(delimiter2); if(pos != std::string::npos) { token = stdStr.substr(0, pos); res = strToUint64_safe(token.c_str(), &timeOfRecord); } else { logE_(_func_,"Didn't find '.' symbol in file_name = ", fileName->mem()); res = Result::Failure; } } else { logE_(_func_,"Didn't find '_' symbol in file_name = ", fileName->mem()); res = Result::Failure; } return res; }
std::string RecpathConfig::GetNextPathForStream() { logD(recpath, _func_); //m_mutex.lock(); if(m_configs.size() == 0) { //m_mutex.unlock(); logD(recpath, _func_, "Config is empty"); return std::string(""); } else logD(recpath, _func_, "Config size is ", m_configs.size()); std::string next_path; while(true) { for(ConfigMap::const_iterator it = m_configs.begin(); it != m_configs.end(); ++it) { Int64 freeSize = MemoryDispatcher::Instance().GetDiskFreeSizeFromDiskname(it->first); logD(recpath, _func_, "diskname is ", it->first.c_str()); logD(recpath, _func_, "freeSize is ", freeSize); if(freeSize > MINFREESIZE) { next_path = it->first; logD(recpath, _func_, "next_path is ", next_path.c_str()); break; } } if(next_path.size()) { break; } else { logD(recpath, _func_, "next_path is empty"); } // cleaning logD(recpath, _func_, "CLEANING"); ChannelChecker::ChannelFileDiskTimes channelFileDiskTimes; std::map<std::string, WeakRef<FFmpegStream> >::iterator itFFStream = m_pStreams->begin(); for(itFFStream; itFFStream != m_pStreams->end(); itFFStream++) { logD(recpath, _func_, "channel_name = ", itFFStream->first.c_str()); Ref<ChannelChecker> channelChecker = itFFStream->second.getRefPtr()->GetChannelChecker(); std::pair<std::string, ChChDiskTimes> oldestFileDiskTimes = channelChecker->GetOldestFileDiskTimes(); logD(recpath, _func_, "filename = ", oldestFileDiskTimes.first.c_str()); logD(recpath, _func_, "diskname = ", oldestFileDiskTimes.second.diskName.c_str()); logD(recpath, _func_, "beginTime = ", oldestFileDiskTimes.second.times.timeStart); logD(recpath, _func_, "endTime = ", oldestFileDiskTimes.second.times.timeEnd); if(oldestFileDiskTimes.first.size()) { channelFileDiskTimes.insert(oldestFileDiskTimes); } } // find most older file int minTime = std::numeric_limits<int>::max(); std::string fileName; std::string diskName; ChannelChecker::ChannelFileDiskTimes::iterator iter = channelFileDiskTimes.begin(); for(iter; iter != channelFileDiskTimes.end(); iter++) { if(minTime > iter->second.times.timeStart) { minTime = iter->second.times.timeStart; fileName = iter->first; diskName = iter->second.diskName; } } logD(recpath, _func_, "minTime = ", minTime); logD(recpath, _func_, "minfileName = ", fileName.c_str()); logD(recpath, _func_, "mindiskName = ", diskName.c_str()); // delete it (if filename is not recorded at current time) StRef<String> dir_name = st_makeString(diskName.c_str()); StRef<String> file_name = st_makeString(fileName.c_str()); StRef<String> full_file_name = st_makeString(dir_name, "/", file_name, ".flv"); if(!MemoryDispatcher::Instance().IsFilenameRecorded(full_file_name->cstr())) { Ref<Vfs> vfs = Vfs::createDefaultLocalVfs (dir_name->mem()); StRef<String> const filenameFull = st_makeString(fileName.c_str(), ".flv"); logD(recpath, _func_, "filenameFull to remove = ", filenameFull); vfs->removeFile (filenameFull->mem()); vfs->removeSubdirsForFilename (filenameFull->mem()); std::string channel_name = fileName.substr(0,fileName.find("/")); (*m_pStreams)[channel_name].getRefPtr()->GetChannelChecker()->DeleteFromCache(diskName, fileName); } else { break; } } //m_mutex.unlock(); return next_path; }
mt_throws Result NativeAsyncFile::open (ConstMemory const filename, Uint32 const open_flags, FileAccessMode const access_mode) { int flags = 0; switch ((FileAccessMode::Value) access_mode) { case FileAccessMode::ReadOnly: flags = O_RDONLY; break; case FileAccessMode::WriteOnly: flags = O_WRONLY; break; case FileAccessMode::ReadWrite: flags = O_RDWR; break; default: unreachable (); } if (open_flags && FileOpenFlags::Create) flags |= O_CREAT; // TODO Specify behavior for Truncate & O_RDONLY combination. if (open_flags & FileOpenFlags::Truncate) flags |= O_TRUNC; // TODO Seek to the end of file instead. O_APPEND semantics is too complicated. if (open_flags & FileOpenFlags::Append) flags |= O_APPEND; StRef<String> const filename_str = st_grab (new (std::nothrow) String (filename)); for (;;) { /* NOTE: man 2 open does not mention EINTR as a possible return * value, while man 3 open _does_. This means that EINTR should * be handled for all invocations of open() in MyCpp (and all * over MyNC). */ fd = ::open (filename_str->cstr(), // Note that O_DIRECT affects kernel-level caching/buffering // and should not be set here. flags | O_NONBLOCK, S_IRUSR | S_IWUSR); if (fd == -1) { if (errno == EINTR) continue; if (errno == EAGAIN) { logD_ (_func, "EAGAIN"); break; } if (errno == EWOULDBLOCK) { logD_ (_func, "EWOULDBLOCK"); break; } exc_throw (PosixException, errno); exc_push_ (IoException); return Result::Failure; } break; } return Result::Success; }