Example #1
0
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;
}
Example #2
0
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());
    }
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}