nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / uibase / dbui / maildispatcher.cxx
blob10d8ea748e6ae1d8913589dd9809f87a6690a126
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <maildispatcher.hxx>
21 #include <imaildsplistener.hxx>
23 #include <algorithm>
25 #include <com/sun/star/mail/MailException.hpp>
26 #include <osl/diagnose.h>
28 using namespace ::com::sun::star;
30 typedef std::vector< ::rtl::Reference<IMailDispatcherListener> > MailDispatcherListenerContainer_t;
32 namespace /* private */
34 class MailDeliveryNotifier
36 public:
37 MailDeliveryNotifier(uno::Reference<mail::XMailMessage> const & message) :
38 message_(message)
41 void operator() (::rtl::Reference<IMailDispatcherListener> const & listener) const
42 { listener->mailDelivered(message_); }
44 private:
45 uno::Reference<mail::XMailMessage> message_;
48 class MailDeliveryErrorNotifier
50 public:
51 MailDeliveryErrorNotifier(
52 ::rtl::Reference<MailDispatcher> const & xMailDispatcher,
53 uno::Reference<mail::XMailMessage> const & message,
54 const OUString& error_message) :
55 mail_dispatcher_(xMailDispatcher),
56 message_(message),
57 error_message_(error_message)
60 void operator() (::rtl::Reference<IMailDispatcherListener> const & listener) const
61 { listener->mailDeliveryError(mail_dispatcher_, message_, error_message_); }
63 private:
64 ::rtl::Reference<MailDispatcher> mail_dispatcher_;
65 uno::Reference<mail::XMailMessage> message_;
66 OUString error_message_;
69 } // namespace private
71 MailDispatcher::MailDispatcher(uno::Reference<mail::XSmtpService> const & mailserver) :
72 m_xMailserver( mailserver ),
73 m_bActive( false ),
74 m_bShutdownRequested( false )
76 m_aWakeupCondition.reset();
77 m_aRunCondition.reset();
79 if (!create())
80 throw uno::RuntimeException();
82 // wait until the mail dispatcher thread is really alive
83 // and has acquired a reference to this instance of the
84 // class
85 m_aRunCondition.wait();
88 MailDispatcher::~MailDispatcher()
92 void MailDispatcher::enqueueMailMessage(uno::Reference<mail::XMailMessage> const & message)
94 ::osl::MutexGuard thread_status_guard( m_aThreadStatusMutex );
95 ::osl::MutexGuard message_container_guard( m_aMessageContainerMutex );
97 OSL_PRECOND( !m_bShutdownRequested, "MailDispatcher thread is shutting down already" );
99 m_aXMessageList.push_back( message );
100 if ( m_bActive )
101 m_aWakeupCondition.set();
104 uno::Reference<mail::XMailMessage> MailDispatcher::dequeueMailMessage()
106 ::osl::MutexGuard guard( m_aMessageContainerMutex );
107 uno::Reference<mail::XMailMessage> message;
108 if ( !m_aXMessageList.empty() )
110 message = m_aXMessageList.front();
111 m_aXMessageList.pop_front();
113 return message;
116 void MailDispatcher::start()
118 OSL_PRECOND(!isStarted(), "MailDispatcher is already started!");
120 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
122 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
124 if ( !m_bShutdownRequested )
126 m_bActive = true;
127 m_aWakeupCondition.set();
128 thread_status_guard.clear();
132 void MailDispatcher::stop()
134 OSL_PRECOND(isStarted(), "MailDispatcher not started!");
136 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
138 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
140 if (!m_bShutdownRequested)
142 m_bActive = false;
143 m_aWakeupCondition.reset();
144 thread_status_guard.clear();
148 void MailDispatcher::shutdown()
150 ::osl::MutexGuard thread_status_guard( m_aThreadStatusMutex );
152 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
154 m_bShutdownRequested = true;
155 m_aWakeupCondition.set();
159 void MailDispatcher::addListener(::rtl::Reference<IMailDispatcherListener> const & listener)
161 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
163 ::osl::MutexGuard guard( m_aListenerContainerMutex );
164 m_aListenerVector.push_back( listener );
167 std::vector< ::rtl::Reference<IMailDispatcherListener> > MailDispatcher::cloneListener()
169 ::osl::MutexGuard guard( m_aListenerContainerMutex );
170 return m_aListenerVector;
173 void MailDispatcher::sendMailMessageNotifyListener(uno::Reference<mail::XMailMessage> const & message)
177 m_xMailserver->sendMailMessage( message );
178 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
179 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
180 MailDeliveryNotifier(message) );
182 catch (const mail::MailException& ex)
184 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
185 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
186 MailDeliveryErrorNotifier(this, message, ex.Message) );
188 catch (const uno::RuntimeException& ex)
190 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
191 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
192 MailDeliveryErrorNotifier(this, message, ex.Message) );
196 void MailDispatcher::run()
198 osl_setThreadName("MailDispatcher");
200 // acquire a self reference in order to avoid race
201 // conditions. The last client of this class must
202 // call shutdown before releasing his last reference
203 // to this class in order to shutdown this thread
204 // which will release his (the very last reference
205 // to the class and so force their destruction
206 m_xSelfReference = this;
208 // signal that the mail dispatcher thread is now alive
209 m_aRunCondition.set();
211 for(;;)
213 m_aWakeupCondition.wait();
215 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
216 if ( m_bShutdownRequested )
217 break;
219 ::osl::ClearableMutexGuard message_container_guard( m_aMessageContainerMutex );
221 if ( !m_aXMessageList.empty() )
223 thread_status_guard.clear();
224 uno::Reference<mail::XMailMessage> message = m_aXMessageList.front();
225 m_aXMessageList.pop_front();
226 message_container_guard.clear();
227 sendMailMessageNotifyListener( message );
229 else // idle - put ourself to sleep
231 m_aWakeupCondition.reset();
232 message_container_guard.clear();
233 thread_status_guard.clear();
234 MailDispatcherListenerContainer_t aListenerListcloned( cloneListener() );
235 for( const auto & l : aListenerListcloned)
236 l->idle();
241 void MailDispatcher::onTerminated()
243 //keep the reference until the end of onTerminated() because of the call order in the
244 //_threadFunc() from osl/thread.hxx
245 m_xSelfReference = nullptr;
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */