Ticket #7731: delay_unlink_fix_bookmark_2.patch

File delay_unlink_fix_bookmark_2.patch, 9.8 KB (added by stichnot@…, 12 years ago)
  • programs/mythtranscode/main.cpp

     
    2828                       ProgramInfo *pginfo);
    2929int BuildKeyframeIndex(MPEG2fixup *m2f, QString &infile,
    3030                       QMap <long long, long long> &posMap, int jobID);
    31 void CompleteJob(int jobID, ProgramInfo *pginfo,
    32                  bool useCutlist, int &resultCode);
     31void CompleteJob(int jobID, ProgramInfo *pginfo, bool useCutlist,
     32                 QMap <long long, int> *deleteMap, int &resultCode);
    3333void UpdateJobQueue(float percent_done);
    3434int CheckJobQueue();
    3535static int glbl_jobID = -1;
     
    674674    }
    675675
    676676    if (jobID >= 0)
    677         CompleteJob(jobID, pginfo, useCutlist, exitcode);
     677        CompleteJob(jobID, pginfo, useCutlist, &deleteMap, exitcode);
    678678
    679679    transcode->deleteLater();
    680680
     
    808808    return 0;
    809809}
    810810
     811long long ComputeNewBookmark(long long oldBookmark,
     812                             QMap<long long, int> *deleteMap)
     813{
     814    if (deleteMap == NULL)
     815        return oldBookmark;
     816    long long subtraction = 0;
     817    long long startOfCutRegion = 0;
     818    QMap<long long, int> delMap = *deleteMap;
     819    bool withinCut = false;
     820    while (delMap.count() && delMap.begin().key() <= oldBookmark)
     821    {
     822        if (delMap.begin().data() == MARK_CUT_START && !withinCut)
     823        {
     824            withinCut = true;
     825            startOfCutRegion = delMap.begin().key();
     826        }
     827        else if (delMap.begin().data() == MARK_CUT_END && withinCut)
     828        {
     829            withinCut = false;
     830            subtraction += (delMap.begin().key() - startOfCutRegion);
     831        }
     832        delMap.remove(delMap.begin());
     833    }
     834    if (withinCut)
     835        subtraction += (oldBookmark - startOfCutRegion);
     836    return oldBookmark - subtraction;
     837}
     838
     839long long ReloadBookmark(ProgramInfo *pginfo)
     840{
     841    MSqlQuery query(MSqlQuery::InitCon());
     842    long long currentBookmark = 0;
     843    query.prepare("SELECT DISTINCT mark FROM recordedmarkup "
     844                  "WHERE chanid = :CHANID "
     845                  "AND starttime = :STARTIME "
     846                  "AND type = :MARKTYPE ;");
     847    query.bindValue(":CHANID", pginfo->chanid);
     848    query.bindValue(":STARTTIME", pginfo->recstartts);
     849    query.bindValue(":MARKTYPE", MARK_BOOKMARK);
     850    if (query.exec() && query.next())
     851    {
     852        currentBookmark = query.value(0).toLongLong();
     853    }
     854    return currentBookmark;
     855}
     856
    811857int transUnlink(QString filename)
    812858{
    813859    if (gContext->GetNumSetting("TruncateDeletesSlowly", 0))
     
    816862    return unlink(filename.toLocal8Bit().constData());
    817863}
    818864
    819 void CompleteJob(int jobID, ProgramInfo *pginfo, bool useCutlist, int &resultCode)
     865void WaitToDelete(ProgramInfo *pginfo)
    820866{
     867    QDateTime startOfWaiting = mythCurrentDateTime();
     868
     869    VERBOSE(VB_GENERAL,
     870            "Transcode: delete old file: "
     871            "waiting while program is in use.");
     872    bool inUse = true;
     873    MSqlQuery query(MSqlQuery::InitCon());
     874    while (inUse)
     875    {
     876        query.prepare("SELECT count(*) FROM inuseprograms "
     877                      "WHERE chanid = :CHANID "
     878                      "AND starttime = :STARTTIME "
     879                      "AND lastupdatetime < :LASTUPDATETIME "
     880                      "AND recusage = 'player' ;");
     881        query.bindValue(":CHANID", pginfo->chanid);
     882        query.bindValue(":STARTTIME", pginfo->recstartts);
     883        query.bindValue(":LASTUPDATETIME", startOfWaiting);
     884        if (!query.exec() || !query.next())
     885        {
     886            VERBOSE(VB_GENERAL,
     887                    "Transcode: delete old file: in-use query failed;");
     888            inUse = false;
     889        }
     890        else
     891        {
     892            inUse = (query.value(0).toUInt() != 0);
     893        }
     894
     895        if (inUse)
     896        {
     897            unsigned secondsToWait = 10;
     898            VERBOSE(VB_GENERAL,
     899                    QString("Transcode: program in use, "
     900                            "rechecking in %1 seconds.").arg(secondsToWait));
     901            sleep(secondsToWait);
     902        }
     903    }
     904    VERBOSE(VB_GENERAL, "Transcode: program is no longer in use.");
     905}
     906
     907void CompleteJob(int jobID, ProgramInfo *pginfo, bool useCutlist,
     908                 QMap <long long, int> *deleteMap, int &resultCode)
     909{
    821910    int status = JobQueue::GetJobStatus(jobID);
    822911
    823912    if (!pginfo)
     
    869958                    .arg(tmpfile).arg(newfile) + ENO);
    870959        }
    871960
     961        MSqlQuery query(MSqlQuery::InitCon());
     962
     963        if (useCutlist)
     964        {
     965            query.prepare("DELETE FROM recordedmarkup "
     966                          "WHERE chanid = :CHANID "
     967                          "AND starttime = :STARTTIME "
     968                          "AND type != :BOOKMARK ");
     969            query.bindValue(":CHANID", pginfo->chanid);
     970            query.bindValue(":STARTTIME", pginfo->recstartts);
     971            query.bindValue(":BOOKMARK", MARK_BOOKMARK);
     972
     973            if (!query.exec())
     974                MythDB::DBError("Error in mythtranscode", query);
     975
     976            query.prepare("UPDATE recorded "
     977                          "SET cutlist = :CUTLIST, "
     978                          "watched = :WATCHED WHERE chanid = :CHANID "
     979                          "AND starttime = :STARTTIME ;");
     980            query.bindValue(":CUTLIST", "0");
     981            query.bindValue(":WATCHED", "0");
     982            query.bindValue(":CHANID", pginfo->chanid);
     983            query.bindValue(":STARTTIME", pginfo->recstartts);
     984
     985            if (!query.exec())
     986                MythDB::DBError("Error in mythtranscode", query);
     987
     988            pginfo->SetCommFlagged(COMM_FLAG_NOT_FLAGGED);
     989        }
     990        else
     991        {
     992            query.prepare("DELETE FROM recordedmarkup "
     993                          "WHERE chanid = :CHANID "
     994                          "AND starttime = :STARTTIME "
     995                          "AND type not in ( :COMM_START, "
     996                          "    :COMM_END, :BOOKMARK, "
     997                          "    :CUTLIST_START, :CUTLIST_END) ;");
     998            query.bindValue(":CHANID", pginfo->chanid);
     999            query.bindValue(":STARTTIME", pginfo->recstartts);
     1000            query.bindValue(":COMM_START", MARK_COMM_START);
     1001            query.bindValue(":COMM_END", MARK_COMM_END);
     1002            query.bindValue(":BOOKMARK", MARK_BOOKMARK);
     1003            query.bindValue(":CUTLIST_START", MARK_CUT_START);
     1004            query.bindValue(":CUTLIST_END", MARK_CUT_END);
     1005
     1006            if (!query.exec())
     1007                MythDB::DBError("Error in mythtranscode", query);
     1008        }
     1009
     1010        // Transcoding may take several minutes.  Reload the bookmark
     1011        // in case it changed, then save its translated value back.
     1012        long long previousBookmark =
     1013            ComputeNewBookmark(ReloadBookmark(pginfo), deleteMap);
     1014        pginfo->SetBookmark(previousBookmark);
     1015
    8721016        if (!gContext->GetNumSetting("SaveTranscoding", 0))
    8731017        {
     1018            WaitToDelete(pginfo);
    8741019            int err;
    8751020            bool followLinks = gContext->GetNumSetting("DeletesFollowLinks", 0);
    8761021
     
    9101055                            .arg(oldfile).arg(strerror(errno)));
    9111056            }
    9121057        }
     1058        // Deleting the file may take a while, especially if the
     1059        // delete waits for the file not to be in use.  Retranslate
     1060        // the bookmark if it was updated during the delete.
     1061        long long currentBookmark = ReloadBookmark(pginfo);
     1062        if (currentBookmark != previousBookmark)
     1063            pginfo->SetBookmark(ComputeNewBookmark(currentBookmark, deleteMap));
    9131064
    9141065        // Delete previews if cutlist was applied.  They will be re-created as
    9151066        // required.  This prevents the user from being stuck with a preview
     
    9711122            }
    9721123        }
    9731124
    974         MSqlQuery query(MSqlQuery::InitCon());
    975 
    976         if (useCutlist)
    977         {
    978             query.prepare("DELETE FROM recordedmarkup "
    979                           "WHERE chanid = :CHANID "
    980                           "AND starttime = :STARTTIME ");
    981             query.bindValue(":CHANID", pginfo->chanid);
    982             query.bindValue(":STARTTIME", pginfo->recstartts);
    983 
    984             if (!query.exec())
    985                 MythDB::DBError("Error in mythtranscode", query);
    986 
    987             query.prepare("UPDATE recorded "
    988                           "SET cutlist = :CUTLIST, bookmark = :BOOKMARK, "
    989                           "watched = :WATCHED WHERE chanid = :CHANID "
    990                           "AND starttime = :STARTTIME ;");
    991             query.bindValue(":CUTLIST", "0");
    992             query.bindValue(":BOOKMARK", "0");
    993             query.bindValue(":WATCHED", "0");
    994             query.bindValue(":CHANID", pginfo->chanid);
    995             query.bindValue(":STARTTIME", pginfo->recstartts);
    996 
    997             if (!query.exec())
    998                 MythDB::DBError("Error in mythtranscode", query);
    999 
    1000             pginfo->SetCommFlagged(COMM_FLAG_NOT_FLAGGED);
    1001         }
    1002         else
    1003         {
    1004             query.prepare("DELETE FROM recordedmarkup "
    1005                           "WHERE chanid = :CHANID "
    1006                           "AND starttime = :STARTTIME "
    1007                           "AND type not in ( :COMM_START, "
    1008                           "    :COMM_END, :BOOKMARK, "
    1009                           "    :CUTLIST_START, :CUTLIST_END) ;");
    1010             query.bindValue(":CHANID", pginfo->chanid);
    1011             query.bindValue(":STARTTIME", pginfo->recstartts);
    1012             query.bindValue(":COMM_START", MARK_COMM_START);
    1013             query.bindValue(":COMM_END", MARK_COMM_END);
    1014             query.bindValue(":BOOKMARK", MARK_BOOKMARK);
    1015             query.bindValue(":CUTLIST_START", MARK_CUT_START);
    1016             query.bindValue(":CUTLIST_END", MARK_CUT_END);
    1017 
    1018             if (!query.exec())
    1019                 MythDB::DBError("Error in mythtranscode", query);
    1020         }
    1021 
    10221125        JobQueue::ChangeJobStatus(jobID, JOB_FINISHED);
    10231126
    10241127    } else {