Deadlocking problem related to Win clipboard thread that still exists
Mike Kaganski
mikekaganski at hotmail.com
Mon Dec 14 06:34:15 UTC 2020
Hi!
This is just a FTR after the nice patch
https://git.libreoffice.org/core/+/9617bc9544cd569066ff187c3672a87fe28fe17f
from Jan-Marek.
With today's Version: 7.2.0.0.alpha0+ (x64)
Build ID: ed07eff77df5af3b214a3791b4455a743ca35853
CPU threads: 12; OS: Windows 10.0 Build 19042; UI render: Skia/Raster;
VCL: win
Locale: ru-RU (ru_RU); UI: en-US
Calc: CL
I see this deadlock (which I also saw before that change, so it is not
any kind of regression from that change).
Main thread:
> win32u.dll!NtUserMsgWaitForMultipleObjectsEx
() Unknown
> user32.dll!RealMsgWaitForMultipleObjectsEx() Unknown
> combase.dll!CCliModalLoop::BlockFn(void * * ahEvent, unsigned long cEvents, unsigned long * lpdwSignaled) Line 2156 C++
> combase.dll!ModalLoop(CSyncClientCall * pClientCall) Line 166 C++
> combase.dll!ClassicSTAThreadDispatchCrossApartmentCall(tagRPCOLEMESSAGE * pMessage, OXIDEntry * pOXIDEntry, CSyncClientCall * pClientCall) Line 319 C++
> [Inline Frame] combase.dll!CSyncClientCall::SwitchAptAndDispatchCall(tagRPCOLEMESSAGE * pMessage) Line 5856 C++
> combase.dll!CSyncClientCall::SendReceive2(tagRPCOLEMESSAGE * pMessage, unsigned long * pstatus) Line 5459 C++
> [Inline Frame] combase.dll!SyncClientCallRetryContext::SendReceiveWithRetry(tagRPCOLEMESSAGE *) Line 1542 C++
> [Inline Frame] combase.dll!CSyncClientCall::SendReceiveInRetryContext(SyncClientCallRetryContext *) Line 565 C++
> combase.dll!ClassicSTAThreadSendReceive(CSyncClientCall * pClientCall, tagRPCOLEMESSAGE * pMsg, unsigned long * pulStatus) Line 547 C++
> combase.dll!CSyncClientCall::SendReceive(tagRPCOLEMESSAGE * pMessage, unsigned long * pulStatus) Line 783 C++
> combase.dll!CClientChannel::SendReceive(tagRPCOLEMESSAGE * pMessage, unsigned long * pulStatus) Line 655 C++
> combase.dll!NdrExtpProxySendReceive(void * pThis, _MIDL_STUB_MESSAGE * pStubMsg) Line 2002 C++
> rpcrt4.dll!NdrpClientCall3() Unknown
> rpcrt4.dll!NdrClientCall3() Unknown
> [Inline Frame] combase.dll!IEnumFORMATETC_RemoteNext_Proxy(IEnumFORMATETC *) Line 1254 C
> combase.dll!IEnumFORMATETC_Next_Proxy(IEnumFORMATETC * This, unsigned long celt, tagFORMATETC * rgelt, unsigned long * pceltFetched) Line 1678 C
> vclplug_winlo.dll!CDOTransferable::initFlavorList() Line 322 C++
> vclplug_winlo.dll!CDOTransferable::create(const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & rxContext, sal::systools::COMReference<IDataObject> pIDataObject) Line 219 C++
> vclplug_winlo.dll!CWinClipboard::getContents() Line 128 C++
> vclplug_winlo.dll!CWinClipboard::ClipboardContentChangedHdl(Timer * __formal) Line 264 C++
> vclplug_winlo.dll!CWinClipboard::LinkStubClipboardContentChangedHdl(void * instance, Timer * data) Line 244 C++
> vcllo.dll!Link<Timer *,void>::Call(Timer * data) Line 111 C++
> vcllo.dll!Timer::Invoke() Line 76 C++
> vcllo.dll!Scheduler::ProcessTaskScheduling() Line 464 C++
> vcllo.dll!Scheduler::CallbackTaskScheduling() Line 267 C++
> vcllo.dll!SalTimer::CallCallback() Line 55 C++
> vclplug_winlo.dll!WinSalTimer::ImplHandleElapsedTimer() Line 164 C++
> vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) Line 479 C++
> vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) Line 525 C++
> vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) Line 444 C++
> vcllo.dll!Application::Reschedule(bool i_bAllEvents) Line 458 C++
> fwklo.dll!framework::StatusIndicatorFactory::impl_reschedule(bool bForce) Line 521 C++
> fwklo.dll!framework::StatusIndicatorFactory::reset(const com::sun::star::uno::Reference<com::sun::star::task::XStatusIndicator> & xChild) Line 169 C++
> fwklo.dll!framework::StatusIndicator::reset() Line 80 C++
> xolo.dll!ProgressBarHelper::SetValue(long nTempValue) Line 82 C++
> xolo.dll!ProgressBarHelper::Increment(long nInc) Line 55 C++
> xolo.dll!XMLTextImportHelper::CreateTextChildContext(SvXMLImport & rImport, long nElement, const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> & xAttrList, XMLTextType eType) Line 1764 C++
> swlo.dll!`anonymous namespace'::SwXMLBodyContentContext_Impl::createFastChildContext(long nElement, const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> & xAttrList) Line 56 C++
> xolo.dll!SvXMLImport::startFastElement(long Element, const com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> & Attribs) Line 780 C++
> expwraplo.dll!`anonymous namespace'::Entity::startElement(const `anonymous-namespace'::Event * pEvent) Line 455 C++
> expwraplo.dll!sax_fastparser::FastSaxParserImpl::consume(`anonymous-namespace'::EventList & rEventList) Line 996 C++
> expwraplo.dll!sax_fastparser::FastSaxParserImpl::parseStream(const com::sun::star::xml::sax::InputSource & rStructSource) Line 846 C++
> expwraplo.dll!sax_fastparser::FastSaxParser::parseStream(const com::sun::star::xml::sax::InputSource & aInputSource) Line 1451 C++
> xolo.dll!SvXMLImport::parseStream(const com::sun::star::xml::sax::InputSource & aInputSource) Line 504 C++
> swlo.dll!`anonymous namespace'::ReadThroughComponent(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & xInputStream, const com::sun::star::uno::Reference<com::sun::star::lang::XComponent> & xModelComponent, const rtl::OUString & rStreamName, const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & rxContext, const char * pFilterName, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> & rFilterArguments, const rtl::OUString & rName, bool bMustBeSuccessfull, bool bEncrypted) Line 180 C++
> swlo.dll!`anonymous namespace'::ReadThroughComponent(const com::sun::star::uno::Reference<com::sun::star::embed::XStorage> & xStorage, const com::sun::star::uno::Reference<com::sun::star::lang::XComponent> & xModelComponent, const char * pStreamName, const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & rxContext, const char * pFilterName, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> & rFilterArguments, const rtl::OUString & rName, bool bMustBeSuccessfull) Line 322 C++
> swlo.dll!XMLReader::Read(SwDoc & rDoc, const rtl::OUString & rBaseURL, SwPaM & rPaM, const rtl::OUString & rName) Line 838 C++
> swlo.dll!SwReader::Read(const Reader & rOptions) Line 191 C++
> swlo.dll!SwDocShell::Load(SfxMedium & rMedium) Line 528 C++
> sfxlo.dll!SfxObjectShell::LoadOwnFormat(SfxMedium & rMedium) Line 3128 C++
> sfxlo.dll!SfxObjectShell::DoLoad(SfxMedium * pMed) Line 677 C++
> sfxlo.dll!SfxBaseModel::load(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & seqArguments) Line 1883 C++
> sfxlo.dll!`anonymous namespace'::SfxFrameLoader_Impl::load(const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & rArgs, const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & _rTargetFrame) Line 681 C++
> fwklo.dll!framework::LoadEnv::impl_loadContent() Line 1163 C++
> fwklo.dll!framework::LoadEnv::start() Line 394 C++
> fwklo.dll!framework::LoadEnv::startLoading(const rtl::OUString & sURL, const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & lMediaDescriptor, const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> & xBaseFrame, const rtl::OUString & sTarget, long nSearchFlags, LoadEnvFeatures eFeature) Line 299 C++
> fwklo.dll!framework::LoadEnv::loadComponentFromURL(const com::sun::star::uno::Reference<com::sun::star::frame::XComponentLoader> & xLoader, const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & xContext, const rtl::OUString & sURL, const rtl::OUString & sTarget, long nSearchFlags, const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & lArgs) Line 168 C++
> fwklo.dll!framework::Desktop::loadComponentFromURL(const rtl::OUString & sURL, const rtl::OUString & sTargetFrameName, long nSearchFlags, const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & lArguments) Line 593 C++
> unotest.dll!unotest::MacrosTest::loadFromDesktop(const rtl::OUString & rURL, const rtl::OUString & rDocService, const com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> & rExtraArgs) Line 63 C++
> swqahelper.dll!SwModelTestBase::loadURL(const rtl::OUString & rURL, const char * pName, const char * pPassword) Line 516 C++
> swqahelper.dll!SwModelTestBase::load(const rtl::OUString & pDir, const char * pName, const char * pPassword) Line 345 C++
> test_sw_uiwriter.dll!testTdf119571_keep_numbering_with_Reject::TestBody() Line 836 C++
> test_sw_uiwriter.dll!std::invoke<void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &>(void(testTdf119571_keep_numbering_with_Reject::*)() & _Obj, testTdf119571_keep_numbering_with_Reject * & _Arg1) Line 1614 C++
> test_sw_uiwriter.dll!std::_Invoker_ret<std::_Unforced,0>::_Call<void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &>(void(testTdf119571_keep_numbering_with_Reject::*)() & _Func, testTdf119571_keep_numbering_with_Reject * & <_Vals_0>) Line 773 C++
> test_sw_uiwriter.dll!std::_Call_binder<std::_Unforced,0,void (__cdecl testTdf119571_keep_numbering_with_Reject::*)(void),std::tuple<testTdf119571_keep_numbering_with_Reject *>,std::tuple<>>(std::_Invoker_ret<std::_Unforced,0> __formal, std::integer_sequence<unsigned __int64,0> __formal, void(testTdf119571_keep_numbering_with_Reject::*)() & _Obj, std::tuple<testTdf119571_keep_numbering_with_Reject *> & _Tpl, std::tuple<> && _Ut) Line 1440 C++
> test_sw_uiwriter.dll!std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &>::operator()<>() Line 1496 C++
> test_sw_uiwriter.dll!std::invoke<std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &> &>(std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &> & _Obj) Line 1585 C++
> test_sw_uiwriter.dll!std::_Invoker_ret<void,1>::_Call<std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &> &>(std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &> & _Func) Line 745 C++
> test_sw_uiwriter.dll!std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,void (__cdecl testTdf119571_keep_numbering_with_Reject::*&)(void),testTdf119571_keep_numbering_with_Reject * &>,void>::_Do_call() Line 948 C++
> test_sw_uiwriter.dll!std::_Func_class<void>::operator()() Line 996 C++
> test_sw_uiwriter.dll!CppUnit::TestCaller<testTdf119571_keep_numbering_with_Reject>::runTest() Line 176 C++
> cppunitd_dll.dll!CppUnit::TestCaseMethodFunctor::operator()() Line 33 C++
> vclbootstrapprotector.dll!`anonymous namespace'::Protector::protect(const CppUnit::Functor & functor, const CppUnit::ProtectorContext & __formal) Line 46 C++
> cppunitd_dll.dll!CppUnit::ProtectorChain::ProtectFunctor::operator()() Line 21 C++
> unobootstrapprotector.dll!`anonymous namespace'::Prot::protect(const CppUnit::Functor & functor, const CppUnit::ProtectorContext & __formal) Line 79 C++
> cppunitd_dll.dll!CppUnit::ProtectorChain::ProtectFunctor::operator()() Line 21 C++
> unoexceptionprotector.dll!`anonymous namespace'::Prot::protect(const CppUnit::Functor & functor, const CppUnit::ProtectorContext & context) Line 62 C++
> cppunitd_dll.dll!CppUnit::ProtectorChain::ProtectFunctor::operator()() Line 21 C++
> cppunitd_dll.dll!CppUnit::DefaultProtector::protect(const CppUnit::Functor & functor, const CppUnit::ProtectorContext & context) Line 15 C++
> cppunitd_dll.dll!CppUnit::ProtectorChain::ProtectFunctor::operator()() Line 21 C++
> cppunitd_dll.dll!CppUnit::ProtectorChain::protect(const CppUnit::Functor & functor, const CppUnit::ProtectorContext & context) Line 86 C++
> cppunitd_dll.dll!CppUnit::TestResult::protect(const CppUnit::Functor & functor, CppUnit::Test * test, const std::string & shortDescription) Line 182 C++
> cppunitd_dll.dll!CppUnit::TestCase::run(CppUnit::TestResult * result) Line 91 C++
> cppunitd_dll.dll!CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult * controller) Line 65 C++
> cppunitd_dll.dll!CppUnit::TestComposite::run(CppUnit::TestResult * result) Line 24 C++
> cppunitd_dll.dll!CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult * controller) Line 65 C++
> cppunitd_dll.dll!CppUnit::TestComposite::run(CppUnit::TestResult * result) Line 24 C++
> cppunitd_dll.dll!CppUnit::TestRunner::WrappingSuite::run(CppUnit::TestResult * result) Line 47 C++
> cppunitd_dll.dll!CppUnit::TestResult::runTest(CppUnit::Test * test) Line 150 C++
> cppunitd_dll.dll!CppUnit::TestRunner::run(CppUnit::TestResult & controller, const std::string & testPath) Line 96 C++
> cppunittester.exe!`anonymous namespace'::ProtectedFixtureFunctor::run() Line 324 C++
> cppunittester.exe!sal_main() Line 474 C++
> cppunittester.exe!main(int argc, char * * argv) Line 381 C++
> cppunittester.exe!invoke_main() Line 79 C++
> cppunittester.exe!__scrt_common_main_seh() Line 288 C++
> cppunittester.exe!__scrt_common_main() Line 331 C++
> cppunittester.exe!mainCRTStartup() Line 17 C++
> kernel32.dll!BaseThreadInitThunk
() Unknown
> ntdll.dll!RtlUserThreadStart
() Unknown
Clipboard thread:
> ntdll.dll!NtWaitForAlertByThreadId
() Unknown
> ntdll.dll!RtlpWaitOnAddressWithTimeout() Unknown
> ntdll.dll!RtlpWaitOnAddress() Unknown
> ntdll.dll!RtlpWaitOnCriticalSection() Unknown
> ntdll.dll!RtlpEnterCriticalSectionContended() Unknown
> ntdll.dll!RtlEnterCriticalSection
() Unknown
> sal3.dll!osl_acquireMutex(_oslMutexImpl * Mutex) Line 66 C++
> vclplug_winlo.dll!osl::Mutex::acquire() Line 57 C++
> vclplug_winlo.dll!SalYieldMutex::doAcquire(unsigned long nLockCount) Line 163 C++
> comphelper.dll!comphelper::SolarMutex::acquire(unsigned long nLockCount) Line 87 C++
> vcllo.dll!osl::Guard<comphelper::SolarMutex>::Guard<comphelper::SolarMutex>(comphelper::SolarMutex & t) Line 136 C++
> vcllo.dll!SolarMutexGuard::SolarMutexGuard() Line 1331 C++
> vcllo.dll!TransferableHelper::lostOwnership(const com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboard> & __formal, const com::sun::star::uno::Reference<com::sun::star::datatransfer::XTransferable> & __formal) Line 453 C++
> vclplug_winlo.dll!CXNotifyingDataObject::lostOwnership() Line 140 C++
> vclplug_winlo.dll!CWinClipboard::onReleaseDataObject(CXNotifyingDataObject * theCaller) Line 325 C++
> vclplug_winlo.dll!CXNotifyingDataObject::Release() Line 77 C++
> combase.dll!CStdIdentity::ReleaseCtrlUnk::__l5::<lambda>() Line 1413 C++
> combase.dll!ObjectMethodExceptionHandlingAction<void <lambda>(void)>(CStdIdentity::ReleaseCtrlUnk::__l5::void <lambda>(void) action, ObjectMethodExceptionHandlingInfo * pExceptionHandlingInfo, ExceptionHandlingResult *) Line 128 C++
> [Inline Frame] combase.dll!CStdIdentity::ReleaseCtrlUnk(unsigned long) Line 1384 C++
> combase.dll!CStdMarshal::DisconnectWorker_ReleasesLock(unsigned long dwType, bool logEventIsActive, CObjectContext * explicitServerContext) Line 4731 C++
> [Inline Frame] combase.dll!CStdMarshal::HandlePendingDisconnect(HRESULT) Line 4275 C++
> combase.dll!CRemoteUnknown::RemReleaseWorker(unsigned short cInterfaceRefs, tagREMINTERFACEREF * InterfaceRefs, int fTopLevel) Line 1307 C++
> rpcrt4.dll!Invoke
() Unknown
> rpcrt4.dll!Ndr64StubWorker() Unknown
> rpcrt4.dll!NdrStubCall3() Unknown
> combase.dll!CStdStubBuffer_Invoke(IRpcStubBuffer * This, tagRPCOLEMESSAGE * prpcmsg, IRpcChannelBuffer * pRpcChannelBuffer) Line 1458 C++
> [Inline Frame] combase.dll!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_c9f3956a20c9da92a64affc24fdd69ec>::operator()() Line 1279 C++
> combase.dll!ObjectMethodExceptionHandlingAction<<lambda_c9f3956a20c9da92a64affc24fdd69ec>>(InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_c9f3956a20c9da92a64affc24fdd69ec> action, ObjectMethodExceptionHandlingInfo * pExceptionHandlingInfo, ExceptionHandlingResult * pExceptionHandlingResult, void *) Line 87 C++
> [Inline Frame] combase.dll!InvokeStubWithExceptionPolicyAndTracing(IRpcStubBuffer * pMsg, tagRPCOLEMESSAGE *) Line 1277 C++
> combase.dll!DefaultStubInvoke(bool bIsAsyncBeginMethod, IServerCall * pServerCall, IRpcChannelBuffer * pChannel, IRpcStubBuffer * pStub, unsigned long * pdwFault) Line 1346 C++
> [Inline Frame] combase.dll!SyncStubCall::Invoke(IServerCall *) Line 1403 C++
> combase.dll!SyncServerCall::StubInvoke(IRpcChannelBuffer * pChannel, IRpcStubBuffer * pStub, unsigned long * pdwFault) Line 781 C++
> [Inline Frame] combase.dll!StubInvoke(tagRPCOLEMESSAGE * pMsg, CStdIdentity * pStdID, IRpcStubBuffer *) Line 1628 C++
> combase.dll!ServerCall::ContextInvoke(tagRPCOLEMESSAGE * pMessage, IRpcStubBuffer * pStub, CServerChannel * pChannel, tagIPIDEntry * pIPIDEntry, unsigned long * pdwFault) Line 1423 C++
> [Inline Frame] combase.dll!CServerChannel::ContextInvoke(tagRPCOLEMESSAGE *) Line 1332 C++
> [Inline Frame] combase.dll!DefaultInvokeInApartment(tagRPCOLEMESSAGE *) Line 3297 C++
> combase.dll!ReentrantSTAInvokeInApartment(tagRPCOLEMESSAGE * pMsg, unsigned long dwCallCat, bool bIsTouchedASTACall, IRpcStubBuffer * pStub, CServerChannel * pChnl, tagIPIDEntry * pIPIDEntry, unsigned long * pdwFault) Line 113 C++
> [Inline Frame] combase.dll!AppInvoke(ServerCall * pStub, CServerChannel *) Line 1122 C++
> combase.dll!ComInvokeWithLockAndIPID(ServerCall * pServerCall, tagIPIDEntry * pIPIDEntry, bool * pbCallerResponsibleForRequestMessageCleanup) Line 2210 C++
> [Inline Frame] combase.dll!ComInvoke(ServerCall *) Line 1697 C++
> [Inline Frame] combase.dll!ThreadDispatch(ServerCall *) Line 414 C++
> combase.dll!ThreadWndProc(HWND__ * window, unsigned int message, unsigned __int64 wparam, __int64 params) Line 740 C++
> user32.dll!UserCallWinProcCheckWow() Unknown
> user32.dll!DispatchMessageWorker() Unknown
> vclplug_winlo.dll!CMtaOleClipboard::run() Line 590 C++
> vclplug_winlo.dll!CMtaOleClipboard::oleThreadProc(void * pParam) Line 614 C++
> ucrtbased.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97 C++
> kernel32.dll!BaseThreadInitThunk
() Unknown
> ntdll.dll!RtlUserThreadStart
() Unknown
The deadlock is because clipboard thread tries to acquire solar mutex
held by main thread (acquired in WinSalTimer::ImplHandleElapsedTimer).
At the same time, main thread calls a method of an COM/OLE object
created in the clipboard thread: it gets it in
CWinClipboard::getContents, and CDOTransferable::create indirectly calls
its CEnumFormatEtc::Next.
Since we (correctly) initialize the clipboard thread for
appartment-threaded object concurrency (see OleInitialize called in
CMtaOleClipboard::run [1]), any call to methods of COM/OLE objects
created in that thread are serialized to that thread. Hence the wait in
the main thread (CCliModalLoop::BlockFn).
I suppose we must check to release solar mutex before any blocking calls
to clipboard thread, including explicit waits (like
CMtaOleClipboard::getClipboard that posts a message and then waits) and
implicit waits like described above, calling COM methods of objects
known to be created in a different thread.
[1]
https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-oleinitialize
--
Best regards,
Mike Kaganski
More information about the LibreOffice
mailing list