Encoder::~Encoder ()
{
- terminate_threads ();
+ try {
+ terminate_threads ();
+ } catch (...) {
+ /* Destructors must not throw exceptions; anything bad
+ happening now is too late to worry about anyway,
+ I think.
+ */
+ }
}
void
Encoder::begin ()
{
if (!EncodeServerFinder::instance()->disabled ()) {
- _server_found_connection = EncodeServerFinder::instance()->ServersListChanged.connect (boost::bind (&Encoder::servers_list_changed, this));
+ weak_ptr<Encoder> wp = shared_from_this ();
+ _server_found_connection = EncodeServerFinder::instance()->ServersListChanged.connect (
+ boost::bind (&Encoder::call_servers_list_changed, wp)
+ );
+ }
+}
+
+/* We don't want the servers-list-changed callback trying to do things
+ during destruction of Encoder, and I think this is the neatest way
+ to achieve that.
+*/
+void
+Encoder::call_servers_list_changed (weak_ptr<Encoder> encoder)
+{
+ shared_ptr<Encoder> e = encoder.lock ();
+ if (e) {
+ e->servers_list_changed ();
}
}
LOG_GENERAL ("Terminating thread %1 of %2", n + 1, _threads.size ());
(*i)->interrupt ();
DCPOMATIC_ASSERT ((*i)->joinable ());
- (*i)->join ();
+ try {
+ (*i)->join ();
+ } catch (boost::thread_interrupted& e) {
+ /* This is to be expected */
+ }
delete *i;
LOG_GENERAL_NC ("Thread terminated");
++n;
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include <boost/thread.hpp>
#include <boost/optional.hpp>
#include <boost/signals2.hpp>
+#include <boost/enable_shared_from_this.hpp>
#include <list>
#include <stdint.h>
* the work around threads and encoding servers.
*/
-class Encoder : public boost::noncopyable, public ExceptionStore
+class Encoder : public boost::noncopyable, public ExceptionStore, public boost::enable_shared_from_this<Encoder>
{
public:
Encoder (boost::shared_ptr<const Film>, boost::shared_ptr<Writer>);
float current_encoding_rate () const;
int video_frames_enqueued () const;
+ void servers_list_changed ();
+
private:
+ static void call_servers_list_changed (boost::weak_ptr<Encoder> encoder);
+
void frame_done ();
void encoder_thread (boost::optional<EncodeServerDescription>);
void terminate_threads ();
- void servers_list_changed ();
/** Film that we are encoding */
boost::shared_ptr<const Film> _film;