Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / dbui / maildispatcher.cxx
blob8af9b180071115bf30ac7ed29f68d9a7b27c1b61
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 <utility>
27 #include <osl/diagnose.h>
29 using namespace ::com::sun::star;
31 typedef std::vector< ::rtl::Reference<IMailDispatcherListener> > MailDispatcherListenerContainer_t;
33 namespace /* private */
35 class MailDeliveryNotifier
37 public:
38 MailDeliveryNotifier(uno::Reference<mail::XMailMessage> message) :
39 message_(std::move(message))
42 void operator() (::rtl::Reference<IMailDispatcherListener> const & listener) const
43 { listener->mailDelivered(message_); }
45 private:
46 uno::Reference<mail::XMailMessage> message_;
49 class MailDeliveryErrorNotifier
51 public:
52 MailDeliveryErrorNotifier(
53 ::rtl::Reference<MailDispatcher> xMailDispatcher,
54 uno::Reference<mail::XMailMessage> message,
55 OUString error_message) :
56 m_mail_dispatcher(std::move(xMailDispatcher)),
57 m_message(std::move(message)),
58 m_error_message(std::move(error_message))
61 void operator() (::rtl::Reference<IMailDispatcherListener> const & listener) const
62 { listener->mailDeliveryError(m_mail_dispatcher, m_message, m_error_message); }
64 private:
65 ::rtl::Reference<MailDispatcher> m_mail_dispatcher;
66 uno::Reference<mail::XMailMessage> m_message;
67 OUString m_error_message;
70 } // namespace private
72 MailDispatcher::MailDispatcher(uno::Reference<mail::XSmtpService> mailserver) :
73 m_xMailserver(std::move( mailserver )),
74 m_bActive( false ),
75 m_bShutdownRequested( false )
77 m_aWakeupCondition.reset();
78 m_aRunCondition.reset();
80 if (!create())
81 throw uno::RuntimeException();
83 // wait until the mail dispatcher thread is really alive
84 // and has acquired a reference to this instance of the
85 // class
86 m_aRunCondition.wait();
89 MailDispatcher::~MailDispatcher()
93 void MailDispatcher::enqueueMailMessage(uno::Reference<mail::XMailMessage> const & message)
95 ::osl::MutexGuard thread_status_guard( m_aThreadStatusMutex );
96 ::osl::MutexGuard message_container_guard( m_aMessageContainerMutex );
98 OSL_PRECOND( !m_bShutdownRequested, "MailDispatcher thread is shutting down already" );
100 m_aXMessageList.push_back( message );
101 if ( m_bActive )
102 m_aWakeupCondition.set();
105 uno::Reference<mail::XMailMessage> MailDispatcher::dequeueMailMessage()
107 ::osl::MutexGuard guard( m_aMessageContainerMutex );
108 uno::Reference<mail::XMailMessage> message;
109 if ( !m_aXMessageList.empty() )
111 message = m_aXMessageList.front();
112 m_aXMessageList.pop_front();
114 return message;
117 void MailDispatcher::start()
119 OSL_PRECOND(!isStarted(), "MailDispatcher is already started!");
121 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
123 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
125 if ( !m_bShutdownRequested )
127 m_bActive = true;
128 m_aWakeupCondition.set();
129 thread_status_guard.clear();
133 void MailDispatcher::stop()
135 OSL_PRECOND(isStarted(), "MailDispatcher not started!");
137 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
139 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
141 if (!m_bShutdownRequested)
143 m_bActive = false;
144 m_aWakeupCondition.reset();
145 thread_status_guard.clear();
149 void MailDispatcher::shutdown()
151 ::osl::MutexGuard thread_status_guard( m_aThreadStatusMutex );
153 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
155 m_bShutdownRequested = true;
156 m_aWakeupCondition.set();
160 void MailDispatcher::addListener(::rtl::Reference<IMailDispatcherListener> const & listener)
162 OSL_PRECOND(!m_bShutdownRequested, "MailDispatcher thread is shutting down already");
164 ::osl::MutexGuard guard( m_aListenerContainerMutex );
165 m_aListenerVector.push_back( listener );
168 std::vector< ::rtl::Reference<IMailDispatcherListener> > MailDispatcher::cloneListener()
170 ::osl::MutexGuard guard( m_aListenerContainerMutex );
171 return m_aListenerVector;
174 void MailDispatcher::sendMailMessageNotifyListener(uno::Reference<mail::XMailMessage> const & message)
178 m_xMailserver->sendMailMessage( message );
179 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
180 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
181 MailDeliveryNotifier(message) );
183 catch (const mail::MailException& ex)
185 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
186 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
187 MailDeliveryErrorNotifier(this, message, ex.Message) );
189 catch (const uno::RuntimeException& ex)
191 MailDispatcherListenerContainer_t aClonedListenerVector(cloneListener());
192 std::for_each( aClonedListenerVector.begin(), aClonedListenerVector.end(),
193 MailDeliveryErrorNotifier(this, message, ex.Message) );
197 void MailDispatcher::run()
199 osl_setThreadName("MailDispatcher");
201 // acquire a self reference in order to avoid race
202 // conditions. The last client of this class must
203 // call shutdown before releasing his last reference
204 // to this class in order to shutdown this thread
205 // which will release his (the very last reference
206 // to the class and so force their destruction
207 m_xSelfReference = this;
209 // signal that the mail dispatcher thread is now alive
210 m_aRunCondition.set();
212 for(;;)
214 m_aWakeupCondition.wait();
216 ::osl::ClearableMutexGuard thread_status_guard( m_aThreadStatusMutex );
217 if ( m_bShutdownRequested )
218 break;
220 ::osl::ClearableMutexGuard message_container_guard( m_aMessageContainerMutex );
222 if ( !m_aXMessageList.empty() )
224 thread_status_guard.clear();
225 uno::Reference<mail::XMailMessage> message = m_aXMessageList.front();
226 m_aXMessageList.pop_front();
227 message_container_guard.clear();
228 sendMailMessageNotifyListener( message );
230 else // idle - put ourself to sleep
232 m_aWakeupCondition.reset();
233 message_container_guard.clear();
234 thread_status_guard.clear();
235 MailDispatcherListenerContainer_t aListenerListcloned( cloneListener() );
236 for( const auto & l : aListenerListcloned)
237 l->idle();
242 void MailDispatcher::onTerminated()
244 //keep the reference until the end of onTerminated() because of the call order in the
245 //_threadFunc() from osl/thread.hxx
246 m_xSelfReference = nullptr;
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */