~michihenning/thumbnailer/no-tmp-file

« back to all changes in this revision

Viewing changes to src/service/main.cpp

  • Committer: Tarmac
  • Author(s): Michi Henning
  • Date: 2015-11-10 03:02:51 UTC
  • mfrom: (293.5.4 safe-shutdown)
  • Revision ID: tarmac-20151110030251-hrk4vaicm4n8726q
Use an advisory lock to prevent shutdown/start-up race between service instances.
Disconnect from DBus at the earliest possible moment so new requests will be redirected to a new instance. Fixes: https://bugs.launchpad.net/bugs/1511553.

Approved by James Henstridge, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "dbusinterface.h"
23
23
#include "dbusinterfaceadaptor.h"
24
24
#include "inactivityhandler.h"
 
25
#include <internal/file_lock.h>
25
26
#include <internal/trace.h>
26
27
#include <service/dbus_names.h>
27
28
 
28
29
#include <QCoreApplication>
29
30
 
30
31
#include <cstdio>
 
32
#include <sys/stat.h>
31
33
 
32
34
using namespace std;
33
35
using namespace unity::thumbnailer::internal;
65
67
    qDebug() << qUtf8Printable("failure cache:   " + get_summary(stats.failure_stats));
66
68
}
67
69
 
 
70
string get_cache_dir()
 
71
{
 
72
    string xdg_base = g_get_user_cache_dir();
 
73
    if (xdg_base == "")
 
74
    {
 
75
        throw runtime_error("Could not determine cache dir");
 
76
    }
 
77
    return xdg_base;
68
78
}
69
79
 
 
80
}  // namespace
 
81
 
70
82
int main(int argc, char** argv)
71
83
{
72
84
    TraceMessageHandler message_handler("thumbnailer-service");
76
88
    {
77
89
        qDebug() << "Initializing";
78
90
 
 
91
        // We keep a lock file while the service is alive. That's to avoid
 
92
        // a shutdown race where a new service instance starts up while
 
93
        // a previous instance is still shutting down, but the leveldb
 
94
        // lock has not been released yet by the previous instance.
 
95
        auto cache_dir = get_cache_dir();
 
96
        ::mkdir(cache_dir.c_str(), 0700);  // May not exist yet.
 
97
        AdvisoryFileLock file_lock(cache_dir + "/thumbnailer-service.lock");
 
98
        if (!file_lock.lock(chrono::milliseconds(10000)))
 
99
        {
 
100
            throw runtime_error("Could not acquire file lock within 10 seconds");
 
101
        }
 
102
 
79
103
        QCoreApplication app(argc, argv);
80
104
 
81
105
        auto inactivity_handler = make_shared<InactivityHandler>([&]{ qDebug() << "Idle timeout reached."; app.quit(); });
85
109
        unity::thumbnailer::service::DBusInterface server(thumbnailer, inactivity_handler);
86
110
        new ThumbnailerAdaptor(&server);
87
111
 
88
 
        unity::thumbnailer::service::AdminInterface admin_server(thumbnailer, inactivity_handler);
 
112
        unity::thumbnailer::service::AdminInterface admin_server(move(thumbnailer), move(inactivity_handler));
89
113
        new ThumbnailerAdminAdaptor(&admin_server);
90
114
 
91
115
        auto bus = QDBusConnection::sessionBus();
96
120
 
97
121
        if (!bus.registerService(BUS_NAME))
98
122
        {
99
 
            throw runtime_error(string("thumbnailer-service: could not acquire DBus name ") + BUS_NAME);
 
123
            throw runtime_error(string("thumbnailer-service: Could not acquire DBus name ") + BUS_NAME);
100
124
        }
101
125
 
102
126
        // Print basic cache stats on start-up. This is useful when examining log entries.
104
128
 
105
129
        rc = app.exec();
106
130
 
 
131
        // Release the bus name as soon as we decide to shut down, otherwise DBus
 
132
        // may still send us requests that we are no longer able to process.
 
133
        if (!bus.unregisterService(BUS_NAME))
 
134
        {
 
135
            throw runtime_error(string("thumbnailer-service: Could not release DBus name ") + BUS_NAME);  // LCOV_EXCL_LINE
 
136
        }
 
137
 
107
138
        qDebug() << "Exiting";
108
139
    }
109
140
    catch (std::exception const& e)