Merge lp:~jamesh/thumbnailer/dbus-handler into lp:thumbnailer/devel
- dbus-handler
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Michi Henning |
Approved revision: | 139 |
Merged at revision: | 133 |
Proposed branch: | lp:~jamesh/thumbnailer/dbus-handler |
Merge into: | lp:thumbnailer/devel |
Diff against target: |
1147 lines (+800/-185) 12 files modified
src/service/CMakeLists.txt (+6/-2) src/service/albumarthandler.cpp (+80/-0) src/service/albumarthandler.h (+59/-0) src/service/artistarthandler.cpp (+80/-0) src/service/artistarthandler.h (+59/-0) src/service/dbusinterface.cpp (+45/-177) src/service/dbusinterface.h (+16/-3) src/service/handler.cpp (+199/-0) src/service/handler.h (+89/-0) src/service/main.cpp (+5/-3) src/service/thumbnailhandler.cpp (+103/-0) src/service/thumbnailhandler.h (+59/-0) |
To merge this branch: | bzr merge lp:~jamesh/thumbnailer/dbus-handler |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Michi Henning (community) | Approve | ||
Review via email: mp+256616@code.launchpad.net |
Commit message
Split out the D-Bus method request handlers into separate classes, with some processing happening in a thread pool (where blocking is permissible) and some in the event loop thread (where blocking is not allowed, but we don't monopolise a thread).
Description of the change
Split the D-Bus method handlers out from the DBusInterface class, and structure them so they can run in three phases. The intended phases are:
1. check() - called in a thread pool, so can perform blocking calls. This method should determine whether it has a valid image available in the cache, and return it if so.
May raise exceptions on failure. If no image is returned, the request moves on to phase 2.
2. download() - called from the event loop, so can not block. This phase is intended to be used to perform actions that don't require a dedicated thread to complete, such as using QNetwork to download data, or QProcess to monitor a child process.
When complete, the handler should call the downloadFinished() slot on success, or sendError() method on failure.
3. check() - called in a thread pool, so can perform blocking calls. This method should use the information gathered from phase 2 to generate a thumbnail, store it in the cache, and return it to the user.
As with phase 1, exceptions can be used to signal failure.
At the moment, none of the code from the Thumbnailer class is set up to handle this split of responsibility, so the first two phases are stubbed out with all the work being done in the third phase. I could have done the work in the first phase, but this ensures that the other two are getting called correctly.
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:136
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:138
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michi Henning (michihenning) wrote : | # |
Looks very good, thanks!
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
- 139. By James Henstridge
-
Merge from devel, fixing conflicts.
PS Jenkins bot (ps-jenkins) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:139
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'src/service/CMakeLists.txt' |
2 | --- src/service/CMakeLists.txt 2015-04-13 04:15:17 +0000 |
3 | +++ src/service/CMakeLists.txt 2015-04-20 05:02:20 +0000 |
4 | @@ -1,15 +1,19 @@ |
5 | add_definitions(${THUMBNAILER_CFLAGS}) |
6 | include_directories(. ${CMAKE_CURRENT_BINARY_DIR}) |
7 | |
8 | -qt5_add_dbus_adaptor(adaptor_files dbusinterface.xml dbusinterface.h DBusInterface) |
9 | +qt5_add_dbus_adaptor(adaptor_files dbusinterface.xml dbusinterface.h unity::thumbnailer::service::DBusInterface) |
10 | |
11 | add_executable(thumbnailer-service |
12 | main.cpp |
13 | dbusinterface.cpp |
14 | + handler.cpp |
15 | + thumbnailhandler.cpp |
16 | + albumarthandler.cpp |
17 | + artistarthandler.cpp |
18 | ${adaptor_files} |
19 | ) |
20 | |
21 | -qt5_use_modules(thumbnailer-service DBus) |
22 | +qt5_use_modules(thumbnailer-service DBus Concurrent) |
23 | target_link_libraries(thumbnailer-service thumbnailer ${CMAKE_THREAD_LIBS_INIT}) |
24 | set_target_properties(thumbnailer-service PROPERTIES AUTOMOC TRUE) |
25 | |
26 | |
27 | === added file 'src/service/albumarthandler.cpp' |
28 | --- src/service/albumarthandler.cpp 1970-01-01 00:00:00 +0000 |
29 | +++ src/service/albumarthandler.cpp 2015-04-20 05:02:20 +0000 |
30 | @@ -0,0 +1,80 @@ |
31 | +/* |
32 | + * Copyright (C) 2015 Canonical, Ltd. |
33 | + * |
34 | + * Authors: |
35 | + * James Henstridge <james.henstridge@canonical.com> |
36 | + * |
37 | + * This library is free software; you can redistribute it and/or modify it under |
38 | + * the terms of version 3 of the GNU General Public License as published |
39 | + * by the Free Software Foundation. |
40 | + * |
41 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
42 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
43 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
44 | + * details. |
45 | + * |
46 | + * You should have received a copy of the GNU General Public License |
47 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
48 | + */ |
49 | + |
50 | +#include "albumarthandler.h" |
51 | + |
52 | +#include <fcntl.h> |
53 | +#include <sys/stat.h> |
54 | +#include <sys/types.h> |
55 | +#include <unistd.h> |
56 | + |
57 | +#include <unity/util/ResourcePtr.h> |
58 | + |
59 | +namespace unity { |
60 | +namespace thumbnailer { |
61 | +namespace service { |
62 | + |
63 | +struct AlbumArtHandlerPrivate { |
64 | + const std::shared_ptr<Thumbnailer> thumbnailer; |
65 | + const QString artist; |
66 | + const QString album; |
67 | + const ThumbnailSize size; |
68 | + |
69 | + AlbumArtHandlerPrivate(const std::shared_ptr<Thumbnailer> &thumbnailer, |
70 | + const QString &artist, |
71 | + const QString &album, |
72 | + ThumbnailSize size) |
73 | + : thumbnailer(thumbnailer), artist(artist), album(album), size(size) { |
74 | + } |
75 | +}; |
76 | + |
77 | +AlbumArtHandler::AlbumArtHandler(const QDBusConnection &bus, |
78 | + const QDBusMessage &message, |
79 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
80 | + const QString &artist, |
81 | + const QString &album, |
82 | + ThumbnailSize size) |
83 | + : Handler(bus, message), p(new AlbumArtHandlerPrivate(thumbnailer, artist, album, size)) { |
84 | +} |
85 | + |
86 | +AlbumArtHandler::~AlbumArtHandler() { |
87 | +} |
88 | + |
89 | +QDBusUnixFileDescriptor AlbumArtHandler::check() { |
90 | + return QDBusUnixFileDescriptor(); |
91 | +} |
92 | + |
93 | +void AlbumArtHandler::download() { |
94 | + downloadFinished(); |
95 | +} |
96 | + |
97 | +QDBusUnixFileDescriptor AlbumArtHandler::create() { |
98 | + std::string art_image = p->thumbnailer->get_album_art( |
99 | + p->artist.toStdString(), p->album.toStdString(), p->size, TN_REMOTE); |
100 | + |
101 | + if (art_image.empty()) { |
102 | + throw std::runtime_error("Could not get thumbnail"); |
103 | + } |
104 | + |
105 | + return write_to_tmpfile(art_image); |
106 | +} |
107 | + |
108 | +} |
109 | +} |
110 | +} |
111 | |
112 | === added file 'src/service/albumarthandler.h' |
113 | --- src/service/albumarthandler.h 1970-01-01 00:00:00 +0000 |
114 | +++ src/service/albumarthandler.h 2015-04-20 05:02:20 +0000 |
115 | @@ -0,0 +1,59 @@ |
116 | +/* |
117 | + * Copyright (C) 2015 Canonical, Ltd. |
118 | + * |
119 | + * Authors: |
120 | + * James Henstridge <james.henstridge@canonical.com> |
121 | + * |
122 | + * This library is free software; you can redistribute it and/or modify it under |
123 | + * the terms of version 3 of the GNU General Public License as published |
124 | + * by the Free Software Foundation. |
125 | + * |
126 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
127 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
128 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
129 | + * details. |
130 | + * |
131 | + * You should have received a copy of the GNU General Public License |
132 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
133 | + */ |
134 | + |
135 | +#pragma once |
136 | + |
137 | +#include "handler.h" |
138 | +#include <thumbnailer.h> |
139 | + |
140 | +#include <memory> |
141 | + |
142 | +#include <QObject> |
143 | +#include <QDBusConnection> |
144 | +#include <QDBusMessage> |
145 | +#include <QDBusUnixFileDescriptor> |
146 | + |
147 | +namespace unity { |
148 | +namespace thumbnailer { |
149 | +namespace service { |
150 | + |
151 | +struct AlbumArtHandlerPrivate; |
152 | + |
153 | +class AlbumArtHandler : public Handler { |
154 | + Q_OBJECT |
155 | +public: |
156 | + AlbumArtHandler(const QDBusConnection &bus, const QDBusMessage &message, |
157 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
158 | + const QString &artist, |
159 | + const QString &album, |
160 | + ThumbnailSize size); |
161 | + ~AlbumArtHandler(); |
162 | + |
163 | +protected: |
164 | + virtual QDBusUnixFileDescriptor check() override; |
165 | + virtual void download() override; |
166 | + virtual QDBusUnixFileDescriptor create() override; |
167 | + |
168 | +private: |
169 | + std::unique_ptr<AlbumArtHandlerPrivate> p; |
170 | +}; |
171 | + |
172 | +} |
173 | +} |
174 | +} |
175 | |
176 | === added file 'src/service/artistarthandler.cpp' |
177 | --- src/service/artistarthandler.cpp 1970-01-01 00:00:00 +0000 |
178 | +++ src/service/artistarthandler.cpp 2015-04-20 05:02:20 +0000 |
179 | @@ -0,0 +1,80 @@ |
180 | +/* |
181 | + * Copyright (C) 2015 Canonical, Ltd. |
182 | + * |
183 | + * Authors: |
184 | + * James Henstridge <james.henstridge@canonical.com> |
185 | + * |
186 | + * This library is free software; you can redistribute it and/or modify it under |
187 | + * the terms of version 3 of the GNU General Public License as published |
188 | + * by the Free Software Foundation. |
189 | + * |
190 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
191 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
192 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
193 | + * details. |
194 | + * |
195 | + * You should have received a copy of the GNU General Public License |
196 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
197 | + */ |
198 | + |
199 | +#include "artistarthandler.h" |
200 | + |
201 | +#include <fcntl.h> |
202 | +#include <sys/stat.h> |
203 | +#include <sys/types.h> |
204 | +#include <unistd.h> |
205 | + |
206 | +#include <unity/util/ResourcePtr.h> |
207 | + |
208 | +namespace unity { |
209 | +namespace thumbnailer { |
210 | +namespace service { |
211 | + |
212 | +struct ArtistArtHandlerPrivate { |
213 | + const std::shared_ptr<Thumbnailer> thumbnailer; |
214 | + const QString artist; |
215 | + const QString album; |
216 | + const ThumbnailSize size; |
217 | + |
218 | + ArtistArtHandlerPrivate(const std::shared_ptr<Thumbnailer> &thumbnailer, |
219 | + const QString &artist, |
220 | + const QString &album, |
221 | + ThumbnailSize size) |
222 | + : thumbnailer(thumbnailer), artist(artist), album(album), size(size) { |
223 | + } |
224 | +}; |
225 | + |
226 | +ArtistArtHandler::ArtistArtHandler(const QDBusConnection &bus, |
227 | + const QDBusMessage &message, |
228 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
229 | + const QString &artist, |
230 | + const QString &album, |
231 | + ThumbnailSize size) |
232 | + : Handler(bus, message), p(new ArtistArtHandlerPrivate(thumbnailer, artist, album, size)) { |
233 | +} |
234 | + |
235 | +ArtistArtHandler::~ArtistArtHandler() { |
236 | +} |
237 | + |
238 | +QDBusUnixFileDescriptor ArtistArtHandler::check() { |
239 | + return QDBusUnixFileDescriptor(); |
240 | +} |
241 | + |
242 | +void ArtistArtHandler::download() { |
243 | + downloadFinished(); |
244 | +} |
245 | + |
246 | +QDBusUnixFileDescriptor ArtistArtHandler::create() { |
247 | + std::string art_image = p->thumbnailer->get_artist_art( |
248 | + p->artist.toStdString(), p->album.toStdString(), p->size, TN_REMOTE); |
249 | + |
250 | + if (art_image.empty()) { |
251 | + throw std::runtime_error("Could not get thumbnail"); |
252 | + } |
253 | + |
254 | + return write_to_tmpfile(art_image); |
255 | +} |
256 | + |
257 | +} |
258 | +} |
259 | +} |
260 | |
261 | === added file 'src/service/artistarthandler.h' |
262 | --- src/service/artistarthandler.h 1970-01-01 00:00:00 +0000 |
263 | +++ src/service/artistarthandler.h 2015-04-20 05:02:20 +0000 |
264 | @@ -0,0 +1,59 @@ |
265 | +/* |
266 | + * Copyright (C) 2015 Canonical, Ltd. |
267 | + * |
268 | + * Authors: |
269 | + * James Henstridge <james.henstridge@canonical.com> |
270 | + * |
271 | + * This library is free software; you can redistribute it and/or modify it under |
272 | + * the terms of version 3 of the GNU General Public License as published |
273 | + * by the Free Software Foundation. |
274 | + * |
275 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
276 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
277 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
278 | + * details. |
279 | + * |
280 | + * You should have received a copy of the GNU General Public License |
281 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
282 | + */ |
283 | + |
284 | +#pragma once |
285 | + |
286 | +#include "handler.h" |
287 | +#include <thumbnailer.h> |
288 | + |
289 | +#include <memory> |
290 | + |
291 | +#include <QObject> |
292 | +#include <QDBusConnection> |
293 | +#include <QDBusMessage> |
294 | +#include <QDBusUnixFileDescriptor> |
295 | + |
296 | +namespace unity { |
297 | +namespace thumbnailer { |
298 | +namespace service { |
299 | + |
300 | +struct ArtistArtHandlerPrivate; |
301 | + |
302 | +class ArtistArtHandler : public Handler { |
303 | + Q_OBJECT |
304 | +public: |
305 | + ArtistArtHandler(const QDBusConnection &bus, const QDBusMessage &message, |
306 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
307 | + const QString &artist, |
308 | + const QString &album, |
309 | + ThumbnailSize size); |
310 | + ~ArtistArtHandler(); |
311 | + |
312 | +protected: |
313 | + virtual QDBusUnixFileDescriptor check() override; |
314 | + virtual void download() override; |
315 | + virtual QDBusUnixFileDescriptor create() override; |
316 | + |
317 | +private: |
318 | + std::unique_ptr<ArtistArtHandlerPrivate> p; |
319 | +}; |
320 | + |
321 | +} |
322 | +} |
323 | +} |
324 | |
325 | === modified file 'src/service/dbusinterface.cpp' |
326 | --- src/service/dbusinterface.cpp 2015-04-16 12:39:55 +0000 |
327 | +++ src/service/dbusinterface.cpp 2015-04-20 05:02:20 +0000 |
328 | @@ -18,34 +18,23 @@ |
329 | */ |
330 | |
331 | #include "dbusinterface.h" |
332 | - |
333 | +#include "thumbnailhandler.h" |
334 | +#include "albumarthandler.h" |
335 | +#include "artistarthandler.h" |
336 | #include <thumbnailer.h> |
337 | |
338 | -#include <internal/safe_strerror.h> |
339 | +#include <map> |
340 | |
341 | #include <QDBusConnection> |
342 | #include <QDBusMessage> |
343 | #include <QDebug> |
344 | -#include <QRunnable> |
345 | -#include <QThreadPool> |
346 | -#include <unity/util/ResourcePtr.h> |
347 | - |
348 | -#include <fcntl.h> |
349 | -#include <sys/stat.h> |
350 | -#include <unistd.h> |
351 | |
352 | using namespace std; |
353 | -using namespace unity::thumbnailer::internal; |
354 | - |
355 | -static const char ART_ERROR[] = "com.canonical.MediaScanner2.Error.Failed"; |
356 | - |
357 | -struct DBusInterfacePrivate { |
358 | - std::shared_ptr<Thumbnailer> thumbnailer = std::make_shared<Thumbnailer>(); |
359 | - QThreadPool pool; |
360 | -}; |
361 | |
362 | namespace { |
363 | |
364 | +const char ART_ERROR[] = "com.canonical.Thubnailer.Error.Failed"; |
365 | + |
366 | ThumbnailSize desiredSizeFromString(const QString &size) |
367 | { |
368 | if (size == "small") { |
369 | @@ -62,16 +51,16 @@ |
370 | throw std::logic_error(error); |
371 | } |
372 | |
373 | -class Task final : public QRunnable { |
374 | -public: |
375 | - Task(std::function<void()> task) : task(task) {} |
376 | - virtual void run() override { |
377 | - task(); |
378 | - } |
379 | -private: |
380 | - std::function<void()> task; |
381 | +} |
382 | + |
383 | +namespace unity { |
384 | +namespace thumbnailer { |
385 | +namespace service { |
386 | + |
387 | +struct DBusInterfacePrivate { |
388 | + std::shared_ptr<Thumbnailer> thumbnailer = std::make_shared<Thumbnailer>(); |
389 | + std::map<Handler*,std::unique_ptr<Handler>> requests; |
390 | }; |
391 | -} |
392 | |
393 | DBusInterface::DBusInterface(QObject *parent) |
394 | : QObject(parent), p(new DBusInterfacePrivate) { |
395 | @@ -80,48 +69,6 @@ |
396 | DBusInterface::~DBusInterface() { |
397 | } |
398 | |
399 | -namespace |
400 | -{ |
401 | - |
402 | -QDBusUnixFileDescriptor write_to_tmpfile(string const& image) |
403 | -{ |
404 | - |
405 | - typedef unity::util::ResourcePtr<int, decltype(&::close)> FdPtr; |
406 | - |
407 | - static auto find_tmpdir = [] |
408 | - { |
409 | - char const* dirp = getenv("TMPDIR"); |
410 | - string dir = dirp ? dirp : "/tmp"; |
411 | - return dir; |
412 | - }; |
413 | - static string dir = find_tmpdir(); |
414 | - |
415 | - int fd = open(dir.c_str(), O_TMPFILE | O_RDWR); |
416 | - if (fd < 0) { |
417 | - string err = "cannot create tmpfile in " + dir + ": " + safe_strerror(errno); |
418 | - throw runtime_error(err); |
419 | - } |
420 | - FdPtr fd_ptr(fd, ::close); |
421 | - auto rc = write(fd_ptr.get(), &image[0], image.size()); |
422 | - if (rc == -1) |
423 | - { |
424 | - string err = "cannot write image data in " + dir + ": " + safe_strerror(errno); |
425 | - throw runtime_error(err); |
426 | - } |
427 | - else if (string::size_type(rc) != image.size()) |
428 | - { |
429 | - string err = "short write for image data in " + dir + |
430 | - "(requested = " + to_string(image.size()) + ", actual = " + to_string(rc) + ")"; |
431 | - throw runtime_error(err); |
432 | - } |
433 | - lseek(fd, SEEK_SET, 0); // No error check needed, can't fail. |
434 | - |
435 | - return QDBusUnixFileDescriptor(fd_ptr.get()); |
436 | -} |
437 | - |
438 | -} |
439 | - |
440 | - |
441 | QDBusUnixFileDescriptor DBusInterface::GetAlbumArt(const QString &artist, const QString &album, const QString &desiredSize) { |
442 | qDebug() << "Look up cover art for" << artist << "/" << album << "at size" << desiredSize; |
443 | |
444 | @@ -133,37 +80,8 @@ |
445 | return QDBusUnixFileDescriptor(); |
446 | } |
447 | |
448 | - setDelayedReply(true); |
449 | - auto thumbnailer = p->thumbnailer; |
450 | - auto bus = connection(); |
451 | - auto msg = message(); |
452 | - p->pool.start(new Task([thumbnailer, artist, album, size, bus, msg]() { |
453 | - std::string art_image; |
454 | - try { |
455 | - art_image = thumbnailer->get_album_art( |
456 | - artist.toStdString(), album.toStdString(), size, TN_REMOTE); |
457 | - } catch (const std::exception &e) { |
458 | - bus.send(msg.createErrorReply(ART_ERROR, e.what())); |
459 | - return; |
460 | - } |
461 | - |
462 | - if (art_image.empty()) { |
463 | - bus.send(msg.createErrorReply(ART_ERROR, "Could not get thumbnail")); |
464 | - return; |
465 | - } |
466 | - |
467 | - try |
468 | - { |
469 | - auto unix_fd = write_to_tmpfile(art_image); |
470 | - bus.send(msg.createReply(QVariant::fromValue(unix_fd))); |
471 | - } |
472 | - catch (runtime_error const& e) |
473 | - { |
474 | - string err = string("GetAlbumArt(): ") + e.what(); |
475 | - bus.send(msg.createErrorReply(ART_ERROR, err.c_str())); |
476 | - } |
477 | - })); |
478 | - |
479 | + queueRequest(new AlbumArtHandler(connection(), message(), p->thumbnailer, |
480 | + artist, album, size)); |
481 | return QDBusUnixFileDescriptor(); |
482 | } |
483 | |
484 | @@ -178,42 +96,13 @@ |
485 | return QDBusUnixFileDescriptor(); |
486 | } |
487 | |
488 | - setDelayedReply(true); |
489 | - auto thumbnailer = p->thumbnailer; |
490 | - auto bus = connection(); |
491 | - auto msg = message(); |
492 | - p->pool.start(new Task([thumbnailer, artist, album, size, bus, msg]() { |
493 | - std::string art_image; |
494 | - try { |
495 | - art_image = thumbnailer->get_artist_art( |
496 | - artist.toStdString(), album.toStdString(), size, TN_REMOTE); |
497 | - } catch (const std::exception &e) { |
498 | - bus.send(msg.createErrorReply(ART_ERROR, e.what())); |
499 | - return; |
500 | - } |
501 | - |
502 | - if (art_image.empty()) { |
503 | - bus.send(msg.createErrorReply(ART_ERROR, "Could not get thumbnail")); |
504 | - return; |
505 | - } |
506 | - |
507 | - try |
508 | - { |
509 | - auto unix_fd = write_to_tmpfile(art_image); |
510 | - bus.send(msg.createReply(QVariant::fromValue(unix_fd))); |
511 | - } |
512 | - catch (runtime_error const& e) |
513 | - { |
514 | - string err = string("GetArtistArt(): ") + e.what(); |
515 | - bus.send(msg.createErrorReply(ART_ERROR, err.c_str())); |
516 | - } |
517 | - })); |
518 | - |
519 | + queueRequest(new ArtistArtHandler(connection(), message(), p->thumbnailer, |
520 | + artist, album, size)); |
521 | return QDBusUnixFileDescriptor(); |
522 | } |
523 | |
524 | QDBusUnixFileDescriptor DBusInterface::GetThumbnail(const QString &filename, const QDBusUnixFileDescriptor &filename_fd, const QString &desiredSize) { |
525 | - qDebug() << "Look thumbnail for" << filename << "at size" << desiredSize; |
526 | + qDebug() << "Create thumbnail for" << filename << "at size" << desiredSize; |
527 | |
528 | ThumbnailSize size; |
529 | try { |
530 | @@ -223,52 +112,31 @@ |
531 | return QDBusUnixFileDescriptor(); |
532 | } |
533 | |
534 | - struct stat filename_stat, fd_stat; |
535 | - if (stat(filename.toUtf8(), &filename_stat) < 0) { |
536 | - sendErrorReply(ART_ERROR, "Could not stat file"); |
537 | - return QDBusUnixFileDescriptor(); |
538 | - } |
539 | - if (fstat(filename_fd.fileDescriptor(), &fd_stat) < 0) { |
540 | - sendErrorReply(ART_ERROR, "Could not stat file descriptor"); |
541 | - return QDBusUnixFileDescriptor(); |
542 | - } |
543 | - if (filename_stat.st_dev != fd_stat.st_dev || |
544 | - filename_stat.st_ino != fd_stat.st_ino) { |
545 | - sendErrorReply(ART_ERROR, "filename refers to a different file to the file descriptor"); |
546 | - return QDBusUnixFileDescriptor(); |
547 | - } |
548 | + queueRequest(new ThumbnailHandler(connection(), message(), p->thumbnailer, |
549 | + filename, filename_fd, size)); |
550 | + return QDBusUnixFileDescriptor(); |
551 | +} |
552 | |
553 | +void DBusInterface::queueRequest(Handler *handler) { |
554 | + p->requests.emplace(handler, std::unique_ptr<Handler>(handler)); |
555 | + connect(handler, &Handler::finished, this, &DBusInterface::requestFinished); |
556 | setDelayedReply(true); |
557 | - auto thumbnailer = p->thumbnailer; |
558 | - auto bus = connection(); |
559 | - auto msg = message(); |
560 | - p->pool.start(new Task([=]() { |
561 | - std::string art; |
562 | - try { |
563 | - art = thumbnailer->get_thumbnail( |
564 | - filename.toStdString(), size, TN_REMOTE); |
565 | - } catch (const std::exception &e) { |
566 | - bus.send(msg.createErrorReply(ART_ERROR, e.what())); |
567 | - return; |
568 | - } |
569 | - |
570 | - if (art.empty()) { |
571 | - bus.send(msg.createErrorReply(ART_ERROR, "Could not get thumbnail")); |
572 | - return; |
573 | - } |
574 | - |
575 | - // FIXME: check that the thumbnail was produced for fd_stat |
576 | - int fd = open(art.c_str(), O_RDONLY); |
577 | - if (fd < 0) { |
578 | - bus.send(msg.createErrorReply(ART_ERROR, safe_strerror(errno).c_str())); |
579 | - return; |
580 | - } |
581 | - |
582 | - QDBusUnixFileDescriptor unix_fd(fd); |
583 | - close(fd); |
584 | - |
585 | - bus.send(msg.createReply(QVariant::fromValue(unix_fd))); |
586 | - })); |
587 | - |
588 | - return QDBusUnixFileDescriptor(); |
589 | + handler->begin(); |
590 | +} |
591 | + |
592 | +void DBusInterface::requestFinished() { |
593 | + Handler *handler = static_cast<Handler*>(sender()); |
594 | + try { |
595 | + auto &h = p->requests.at(handler); |
596 | + h.release(); |
597 | + p->requests.erase(handler); |
598 | + } catch (const std::out_of_range &e) { |
599 | + qWarning() << "finished() called on unknown handler" << handler; |
600 | + } |
601 | + // Queue deletion of handler when we re-enter the event loop. |
602 | + handler->deleteLater(); |
603 | +} |
604 | + |
605 | +} |
606 | +} |
607 | } |
608 | |
609 | === modified file 'src/service/dbusinterface.h' |
610 | --- src/service/dbusinterface.h 2015-04-13 01:58:39 +0000 |
611 | +++ src/service/dbusinterface.h 2015-04-20 05:02:20 +0000 |
612 | @@ -17,8 +17,9 @@ |
613 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
614 | */ |
615 | |
616 | -#ifndef DBUSINTERFACE_H |
617 | -#define DBUSINTERFACE_H |
618 | +#pragma once |
619 | + |
620 | +#include "handler.h" |
621 | |
622 | #include <memory> |
623 | |
624 | @@ -27,6 +28,10 @@ |
625 | #include <QObject> |
626 | #include <QString> |
627 | |
628 | +namespace unity { |
629 | +namespace thumbnailer { |
630 | +namespace service { |
631 | + |
632 | struct DBusInterfacePrivate; |
633 | |
634 | class DBusInterface : public QObject, protected QDBusContext { |
635 | @@ -44,7 +49,15 @@ |
636 | QDBusUnixFileDescriptor GetThumbnail(const QString &filename, const QDBusUnixFileDescriptor &filename_fd, const QString &desiredSize); |
637 | |
638 | private: |
639 | + void queueRequest(Handler* handler); |
640 | + |
641 | +private Q_SLOTS: |
642 | + void requestFinished(); |
643 | + |
644 | +private: |
645 | std::unique_ptr<DBusInterfacePrivate> p; |
646 | }; |
647 | |
648 | -#endif |
649 | +} |
650 | +} |
651 | +} |
652 | |
653 | === added file 'src/service/handler.cpp' |
654 | --- src/service/handler.cpp 1970-01-01 00:00:00 +0000 |
655 | +++ src/service/handler.cpp 2015-04-20 05:02:20 +0000 |
656 | @@ -0,0 +1,199 @@ |
657 | +/* |
658 | + * Copyright (C) 2015 Canonical, Ltd. |
659 | + * |
660 | + * Authors: |
661 | + * James Henstridge <james.henstridge@canonical.com> |
662 | + * |
663 | + * This library is free software; you can redistribute it and/or modify it under |
664 | + * the terms of version 3 of the GNU General Public License as published |
665 | + * by the Free Software Foundation. |
666 | + * |
667 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
668 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
669 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
670 | + * details. |
671 | + * |
672 | + * You should have received a copy of the GNU General Public License |
673 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
674 | + */ |
675 | + |
676 | +#include "handler.h" |
677 | +#include <internal/safe_strerror.h> |
678 | + |
679 | +#include <fcntl.h> |
680 | +#include <sys/stat.h> |
681 | +#include <sys/types.h> |
682 | +#include <unistd.h> |
683 | + |
684 | +#include <QtConcurrent> |
685 | +#include <QFuture> |
686 | +#include <QFutureWatcher> |
687 | +#include <QDebug> |
688 | +#include <unity/util/ResourcePtr.h> |
689 | + |
690 | +using namespace unity::thumbnailer::internal; |
691 | + |
692 | +namespace { |
693 | +const char ART_ERROR[] = "com.canonical.Thumbnailer.Error.Failed"; |
694 | + |
695 | +struct FdOrError { |
696 | + QDBusUnixFileDescriptor fd; |
697 | + QString error; |
698 | +}; |
699 | +} |
700 | + |
701 | +namespace unity { |
702 | +namespace thumbnailer { |
703 | +namespace service { |
704 | + |
705 | +struct HandlerPrivate { |
706 | + QDBusConnection bus; |
707 | + const QDBusMessage message; |
708 | + |
709 | + bool cancelled = false; |
710 | + QFutureWatcher<FdOrError> checkWatcher; |
711 | + QFutureWatcher<FdOrError> createWatcher; |
712 | + |
713 | + HandlerPrivate(const QDBusConnection &bus, const QDBusMessage &message) |
714 | + : bus(bus), message(message) { |
715 | + } |
716 | +}; |
717 | + |
718 | +Handler::Handler(const QDBusConnection &bus, const QDBusMessage &message) |
719 | + : p(new HandlerPrivate(bus, message)) { |
720 | + connect(&p->checkWatcher, &QFutureWatcher<FdOrError>::finished, |
721 | + this, &Handler::checkFinished); |
722 | + connect(&p->createWatcher, &QFutureWatcher<FdOrError>::finished, |
723 | + this, &Handler::createFinished); |
724 | +} |
725 | + |
726 | +Handler::~Handler() { |
727 | + p->cancelled = true; |
728 | + // ensure that jobs occurring in the thread pool complete. |
729 | + p->checkWatcher.waitForFinished(); |
730 | + p->createWatcher.waitForFinished(); |
731 | + qDebug() << "Handler" << this << "destroyed"; |
732 | +} |
733 | + |
734 | +void Handler::begin() { |
735 | + auto do_check = [this]() -> FdOrError { |
736 | + try { |
737 | + return FdOrError{check(), nullptr}; |
738 | + } catch (const std::exception &e) { |
739 | + return FdOrError{QDBusUnixFileDescriptor(), e.what()}; |
740 | + } |
741 | + }; |
742 | + p->checkWatcher.setFuture(QtConcurrent::run(do_check)); |
743 | +} |
744 | + |
745 | +void Handler::checkFinished() { |
746 | + if (p->cancelled) |
747 | + return; |
748 | + |
749 | + FdOrError fd_error; |
750 | + try { |
751 | + fd_error = p->checkWatcher.result(); |
752 | + } catch (const std::exception &e) { |
753 | + sendError(e.what()); |
754 | + return; |
755 | + } |
756 | + if (!fd_error.error.isNull()) { |
757 | + sendError(fd_error.error); |
758 | + return; |
759 | + } |
760 | + // Did we find a valid thumbnail in the cache? |
761 | + if (fd_error.fd.isValid()) { |
762 | + sendThumbnail(fd_error.fd); |
763 | + } else { |
764 | + // otherwise move on to the download phase. |
765 | + download(); |
766 | + } |
767 | +} |
768 | + |
769 | +void Handler::downloadFinished() { |
770 | + if (p->cancelled) |
771 | + return; |
772 | + |
773 | + auto do_create = [this]() -> FdOrError { |
774 | + try { |
775 | + return FdOrError{create(), nullptr}; |
776 | + } catch (const std::exception &e) { |
777 | + return FdOrError{QDBusUnixFileDescriptor(), e.what()}; |
778 | + } |
779 | + }; |
780 | + p->createWatcher.setFuture(QtConcurrent::run(do_create)); |
781 | +} |
782 | + |
783 | +void Handler::createFinished() { |
784 | + if (p->cancelled) |
785 | + return; |
786 | + |
787 | + FdOrError fd_error; |
788 | + try { |
789 | + fd_error = p->createWatcher.result(); |
790 | + } catch (const std::exception &e) { |
791 | + sendError(e.what()); |
792 | + return; |
793 | + } |
794 | + if (!fd_error.error.isEmpty()) { |
795 | + sendError(fd_error.error); |
796 | + return; |
797 | + } |
798 | + // Did we find a valid thumbnail in the cache? |
799 | + if (fd_error.fd.isValid()) { |
800 | + sendThumbnail(fd_error.fd); |
801 | + } else { |
802 | + // otherwise move on to the download phase. |
803 | + download(); |
804 | + } |
805 | +} |
806 | + |
807 | +void Handler::sendThumbnail(const QDBusUnixFileDescriptor &unix_fd) { |
808 | + p->bus.send(p->message.createReply(QVariant::fromValue(unix_fd))); |
809 | + Q_EMIT finished(); |
810 | +} |
811 | + |
812 | +void Handler::sendError(const QString &error) { |
813 | + p->bus.send(p->message.createErrorReply(ART_ERROR, error)); |
814 | + Q_EMIT finished(); |
815 | +} |
816 | + |
817 | +QDBusUnixFileDescriptor write_to_tmpfile(std::string const& image) |
818 | +{ |
819 | + |
820 | + typedef unity::util::ResourcePtr<int, decltype(&::close)> FdPtr; |
821 | + |
822 | + static auto find_tmpdir = [] |
823 | + { |
824 | + char const* dirp = getenv("TMPDIR"); |
825 | + std::string dir = dirp ? dirp : "/tmp"; |
826 | + return dir; |
827 | + }; |
828 | + static std::string dir = find_tmpdir(); |
829 | + |
830 | + int fd = open(dir.c_str(), O_TMPFILE | O_RDWR); |
831 | + if (fd < 0) { |
832 | + std::string err = "cannot create tmpfile in " + dir + ": " + safe_strerror(errno); |
833 | + throw std::runtime_error(err); |
834 | + } |
835 | + FdPtr fd_ptr(fd, ::close); |
836 | + auto rc = write(fd_ptr.get(), &image[0], image.size()); |
837 | + if (rc == -1) |
838 | + { |
839 | + std::string err = "cannot write image data in " + dir + ": " + safe_strerror(errno); |
840 | + throw std::runtime_error(err); |
841 | + } |
842 | + else if (std::string::size_type(rc) != image.size()) |
843 | + { |
844 | + std::string err = "short write for image data in " + dir + |
845 | + "(requested = " + std::to_string(image.size()) + ", actual = " + std::to_string(rc) + ")"; |
846 | + throw std::runtime_error(err); |
847 | + } |
848 | + lseek(fd, SEEK_SET, 0); // No error check needed, can't fail. |
849 | + |
850 | + return QDBusUnixFileDescriptor(fd_ptr.get()); |
851 | +} |
852 | + |
853 | +} |
854 | +} |
855 | +} |
856 | |
857 | === added file 'src/service/handler.h' |
858 | --- src/service/handler.h 1970-01-01 00:00:00 +0000 |
859 | +++ src/service/handler.h 2015-04-20 05:02:20 +0000 |
860 | @@ -0,0 +1,89 @@ |
861 | +/* |
862 | + * Copyright (C) 2015 Canonical, Ltd. |
863 | + * |
864 | + * Authors: |
865 | + * James Henstridge <james.henstridge@canonical.com> |
866 | + * |
867 | + * This library is free software; you can redistribute it and/or modify it under |
868 | + * the terms of version 3 of the GNU General Public License as published |
869 | + * by the Free Software Foundation. |
870 | + * |
871 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
872 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
873 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
874 | + * details. |
875 | + * |
876 | + * You should have received a copy of the GNU General Public License |
877 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
878 | + */ |
879 | + |
880 | +#pragma once |
881 | + |
882 | +#include <memory> |
883 | +#include <string> |
884 | + |
885 | +#include <QObject> |
886 | +#include <QDBusConnection> |
887 | +#include <QDBusMessage> |
888 | +#include <QDBusUnixFileDescriptor> |
889 | + |
890 | +namespace unity { |
891 | +namespace thumbnailer { |
892 | +namespace service { |
893 | + |
894 | +struct HandlerPrivate; |
895 | + |
896 | +class Handler : public QObject { |
897 | + Q_OBJECT |
898 | +public: |
899 | + Handler(const QDBusConnection &bus, const QDBusMessage &message); |
900 | + ~Handler(); |
901 | + |
902 | + Handler(const Handler&) = delete; |
903 | + Handler& operator=(Handler&) = delete; |
904 | + |
905 | + void begin(); |
906 | + |
907 | +protected: |
908 | + void sendThumbnail(const QDBusUnixFileDescriptor &unix_fd); |
909 | + void sendError(const QString &error); |
910 | + |
911 | + // Methods to be overridden by handlers |
912 | + |
913 | + // check() determines whether the requested thumbnail exists in |
914 | + // the cache. It is called synchronously in the thread pool. |
915 | + // |
916 | + // If it is available, it should be returned as a file descriptor, |
917 | + // which will be returned to the user. |
918 | + // |
919 | + // If not, processing will continue. |
920 | + virtual QDBusUnixFileDescriptor check() = 0; |
921 | + |
922 | + // download() is expected to perform any asynchronous actions and |
923 | + // end the request by either calling the downloadFinished() slot |
924 | + // or sendError(). |
925 | + virtual void download() = 0; |
926 | + |
927 | + // create() should create the thumbnail and store it in the cache, |
928 | + // and return it as a file descriptor. It is called synchronously |
929 | + // in the thread pool. |
930 | + virtual QDBusUnixFileDescriptor create() = 0; |
931 | + |
932 | +protected Q_SLOTS: |
933 | + void checkFinished(); |
934 | + void downloadFinished(); |
935 | + void createFinished(); |
936 | + |
937 | +Q_SIGNALS: |
938 | + void finished(); |
939 | + |
940 | +private: |
941 | + std::unique_ptr<HandlerPrivate> p; |
942 | +}; |
943 | + |
944 | +// Helper routine for creating an unnamed tmpfile from image data |
945 | +QDBusUnixFileDescriptor write_to_tmpfile(std::string const& image); |
946 | + |
947 | +} |
948 | +} |
949 | +} |
950 | |
951 | === modified file 'src/service/main.cpp' |
952 | --- src/service/main.cpp 2015-04-01 08:53:21 +0000 |
953 | +++ src/service/main.cpp 2015-04-20 05:02:20 +0000 |
954 | @@ -5,6 +5,8 @@ |
955 | #include "dbusinterface.h" |
956 | #include "dbusinterfaceadaptor.h" |
957 | |
958 | +using namespace unity::thumbnailer::service; |
959 | + |
960 | static const char BUS_NAME[] = "com.canonical.Thumbnailer"; |
961 | static const char BUS_PATH[] = "/com/canonical/Thumbnailer"; |
962 | |
963 | @@ -13,9 +15,9 @@ |
964 | |
965 | auto bus = QDBusConnection::sessionBus(); |
966 | |
967 | - auto server = new DBusInterface(); |
968 | - new ThumbnailerAdaptor(server); |
969 | - bus.registerObject(BUS_PATH, server); |
970 | + unity::thumbnailer::service::DBusInterface server; |
971 | + new ThumbnailerAdaptor(&server); |
972 | + bus.registerObject(BUS_PATH, &server); |
973 | |
974 | if (!bus.registerService(BUS_NAME)) { |
975 | fprintf(stderr, "Could no acquire D-Bus name %s.\n", BUS_NAME); |
976 | |
977 | === added file 'src/service/thumbnailhandler.cpp' |
978 | --- src/service/thumbnailhandler.cpp 1970-01-01 00:00:00 +0000 |
979 | +++ src/service/thumbnailhandler.cpp 2015-04-20 05:02:20 +0000 |
980 | @@ -0,0 +1,103 @@ |
981 | +/* |
982 | + * Copyright (C) 2015 Canonical, Ltd. |
983 | + * |
984 | + * Authors: |
985 | + * James Henstridge <james.henstridge@canonical.com> |
986 | + * |
987 | + * This library is free software; you can redistribute it and/or modify it under |
988 | + * the terms of version 3 of the GNU General Public License as published |
989 | + * by the Free Software Foundation. |
990 | + * |
991 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
992 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
993 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
994 | + * details. |
995 | + * |
996 | + * You should have received a copy of the GNU General Public License |
997 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
998 | + */ |
999 | + |
1000 | +#include "thumbnailhandler.h" |
1001 | +#include <internal/safe_strerror.h> |
1002 | + |
1003 | +#include <fcntl.h> |
1004 | +#include <sys/stat.h> |
1005 | +#include <sys/types.h> |
1006 | +#include <unistd.h> |
1007 | + |
1008 | +#include <unity/util/ResourcePtr.h> |
1009 | + |
1010 | +using namespace unity::thumbnailer::internal; |
1011 | + |
1012 | +namespace unity { |
1013 | +namespace thumbnailer { |
1014 | +namespace service { |
1015 | + |
1016 | +struct ThumbnailHandlerPrivate { |
1017 | + const std::shared_ptr<Thumbnailer> thumbnailer; |
1018 | + const QString filename; |
1019 | + const QDBusUnixFileDescriptor filename_fd; |
1020 | + const ThumbnailSize size; |
1021 | + |
1022 | + ThumbnailHandlerPrivate(const std::shared_ptr<Thumbnailer> &thumbnailer, |
1023 | + const QString &filename, |
1024 | + const QDBusUnixFileDescriptor &filename_fd, |
1025 | + ThumbnailSize size) |
1026 | + : thumbnailer(thumbnailer), filename(filename), |
1027 | + filename_fd(filename_fd), size(size) { |
1028 | + } |
1029 | +}; |
1030 | + |
1031 | +ThumbnailHandler::ThumbnailHandler(const QDBusConnection &bus, |
1032 | + const QDBusMessage &message, |
1033 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
1034 | + const QString &filename, |
1035 | + const QDBusUnixFileDescriptor &filename_fd, |
1036 | + ThumbnailSize size) |
1037 | + : Handler(bus, message), p(new ThumbnailHandlerPrivate(thumbnailer, filename, filename_fd, size)) { |
1038 | +} |
1039 | + |
1040 | +ThumbnailHandler::~ThumbnailHandler() { |
1041 | +} |
1042 | + |
1043 | +QDBusUnixFileDescriptor ThumbnailHandler::check() { |
1044 | + return QDBusUnixFileDescriptor(); |
1045 | +} |
1046 | + |
1047 | +void ThumbnailHandler::download() { |
1048 | + downloadFinished(); |
1049 | +} |
1050 | + |
1051 | +QDBusUnixFileDescriptor ThumbnailHandler::create() { |
1052 | + typedef unity::util::ResourcePtr<int, decltype(&::close)> FdPtr; |
1053 | + struct stat filename_stat, fd_stat; |
1054 | + |
1055 | + if (stat(p->filename.toUtf8(), &filename_stat) < 0) { |
1056 | + throw std::runtime_error("Could not stat file"); |
1057 | + } |
1058 | + if (fstat(p->filename_fd.fileDescriptor(), &fd_stat) < 0) { |
1059 | + throw std::runtime_error("Could not stat file descriptor"); |
1060 | + } |
1061 | + if (filename_stat.st_dev != fd_stat.st_dev || |
1062 | + filename_stat.st_ino != fd_stat.st_ino) { |
1063 | + throw std::runtime_error("filename refers to a different file to the file descriptor"); |
1064 | + } |
1065 | + |
1066 | + std::string art = p->thumbnailer->get_thumbnail( |
1067 | + p->filename.toStdString(), p->size, TN_REMOTE); |
1068 | + |
1069 | + if (art.empty()) { |
1070 | + throw std::runtime_error("Could not get thumbnail"); |
1071 | + } |
1072 | + |
1073 | + // FIXME: check that the thumbnail was produced for fd_stat |
1074 | + FdPtr fd(open(art.c_str(), O_RDONLY), ::close); |
1075 | + if (fd.get() < 0) { |
1076 | + throw std::runtime_error(safe_strerror(errno)); |
1077 | + } |
1078 | + return QDBusUnixFileDescriptor(fd.get()); |
1079 | +} |
1080 | + |
1081 | +} |
1082 | +} |
1083 | +} |
1084 | |
1085 | === added file 'src/service/thumbnailhandler.h' |
1086 | --- src/service/thumbnailhandler.h 1970-01-01 00:00:00 +0000 |
1087 | +++ src/service/thumbnailhandler.h 2015-04-20 05:02:20 +0000 |
1088 | @@ -0,0 +1,59 @@ |
1089 | +/* |
1090 | + * Copyright (C) 2015 Canonical, Ltd. |
1091 | + * |
1092 | + * Authors: |
1093 | + * James Henstridge <james.henstridge@canonical.com> |
1094 | + * |
1095 | + * This library is free software; you can redistribute it and/or modify it under |
1096 | + * the terms of version 3 of the GNU General Public License as published |
1097 | + * by the Free Software Foundation. |
1098 | + * |
1099 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1100 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1101 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
1102 | + * details. |
1103 | + * |
1104 | + * You should have received a copy of the GNU General Public License |
1105 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1106 | + */ |
1107 | + |
1108 | +#pragma once |
1109 | + |
1110 | +#include "handler.h" |
1111 | +#include <thumbnailer.h> |
1112 | + |
1113 | +#include <memory> |
1114 | + |
1115 | +#include <QObject> |
1116 | +#include <QDBusConnection> |
1117 | +#include <QDBusMessage> |
1118 | +#include <QDBusUnixFileDescriptor> |
1119 | + |
1120 | +namespace unity { |
1121 | +namespace thumbnailer { |
1122 | +namespace service { |
1123 | + |
1124 | +struct ThumbnailHandlerPrivate; |
1125 | + |
1126 | +class ThumbnailHandler : public Handler { |
1127 | + Q_OBJECT |
1128 | +public: |
1129 | + ThumbnailHandler(const QDBusConnection &bus, const QDBusMessage &message, |
1130 | + const std::shared_ptr<Thumbnailer> &thumbnailer, |
1131 | + const QString &filename, |
1132 | + const QDBusUnixFileDescriptor &filename_fd, |
1133 | + ThumbnailSize size); |
1134 | + ~ThumbnailHandler(); |
1135 | + |
1136 | +protected: |
1137 | + virtual QDBusUnixFileDescriptor check() override; |
1138 | + virtual void download() override; |
1139 | + virtual QDBusUnixFileDescriptor create() override; |
1140 | + |
1141 | +private: |
1142 | + std::unique_ptr<ThumbnailHandlerPrivate> p; |
1143 | +}; |
1144 | + |
1145 | +} |
1146 | +} |
1147 | +} |
FAILED: Continuous integration, rev:135 /code.launchpad .net/~jamesh/ thumbnailer/ dbus-handler/ +merge/ 256616/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ thumbnailer- devel-ci/ 31/ jenkins. qa.ubuntu. com/job/ thumbnailer- devel-vivid- amd64-ci/ 31 jenkins. qa.ubuntu. com/job/ thumbnailer- devel-vivid- armhf-ci/ 31 jenkins. qa.ubuntu. com/job/ thumbnailer- devel-vivid- armhf-ci/ 31/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ thumbnailer- devel-vivid- i386-ci/ 31
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/thumbnailer -devel- ci/31/rebuild
http://