LibreOffice Module vcl (master)  1
runinmain.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #ifndef INCLUDED_VCL_INC_OSX_RUNINMAIN_HXX
21 #define INCLUDED_VCL_INC_OSX_RUNINMAIN_HXX
22 
41 #include <unordered_map>
42 
43 #include <Block.h>
44 
45 #include <osl/thread.h>
46 
47 #include "saltimer.h"
48 #include <salframe.hxx>
49 #include <tools/debug.hxx>
50 
52 {
53  void* pointer;
54  bool boolean;
56 
58 };
59 
60 #define OSX_RUNINMAIN_MEMBERS \
61  std::mutex m_runInMainMutex; \
62  std::condition_variable m_aInMainCondition; \
63  std::condition_variable m_aResultCondition; \
64  bool m_wakeUpMain = false; \
65  bool m_resultReady = false; \
66  RuninmainBlock m_aCodeBlock; \
67  RuninmainResult m_aResult;
68 
69 #define OSX_RUNINMAIN( instance, command ) \
70  if ( !instance->IsMainThread() ) \
71  { \
72  DBG_TESTSOLARMUTEX(); \
73  SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \
74  { \
75  std::scoped_lock<std::mutex> g(aMutex->m_runInMainMutex); \
76  assert( !aMutex->m_aCodeBlock ); \
77  aMutex->m_aCodeBlock = Block_copy(^{ \
78  command; \
79  }); \
80  aMutex->m_wakeUpMain = true; \
81  aMutex->m_aInMainCondition.notify_all(); \
82  } \
83  dispatch_async(dispatch_get_main_queue(),^{ \
84  ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \
85  }); \
86  { \
87  std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \
88  aMutex->m_aResultCondition.wait( \
89  g, [&aMutex]() { return aMutex->m_resultReady; }); \
90  aMutex->m_resultReady = false; \
91  } \
92  return; \
93  }
94 
95 #define OSX_RUNINMAIN_POINTER( instance, command, type ) \
96  if ( !instance->IsMainThread() ) \
97  { \
98  DBG_TESTSOLARMUTEX(); \
99  SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \
100  { \
101  std::scoped_lock<std::mutex> g(aMutex->m_runInMainMutex); \
102  assert( !aMutex->m_aCodeBlock ); \
103  aMutex->m_aCodeBlock = Block_copy(^{ \
104  aMutex->m_aResult.pointer = static_cast<void*>( command ); \
105  }); \
106  aMutex->m_wakeUpMain = true; \
107  aMutex->m_aInMainCondition.notify_all(); \
108  } \
109  dispatch_async(dispatch_get_main_queue(),^{ \
110  ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \
111  }); \
112  { \
113  std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \
114  aMutex->m_aResultCondition.wait( \
115  g, [&aMutex]() { return aMutex->m_resultReady; }); \
116  aMutex->m_resultReady = false; \
117  } \
118  return static_cast<type>( aMutex->m_aResult.pointer ); \
119  }
120 
121 #define OSX_RUNINMAIN_UNION( instance, command, member ) \
122  if ( !instance->IsMainThread() ) \
123  { \
124  DBG_TESTSOLARMUTEX(); \
125  SalYieldMutex *aMutex = static_cast<SalYieldMutex*>(instance->GetYieldMutex()); \
126  { \
127  std::scoped_lock<std::mutex> g(aMutex->m_runInMainMutex); \
128  assert( !aMutex->m_aCodeBlock ); \
129  aMutex->m_aCodeBlock = Block_copy(^{ \
130  aMutex->m_aResult.member = command; \
131  }); \
132  aMutex->m_wakeUpMain = true; \
133  aMutex->m_aInMainCondition.notify_all(); \
134  } \
135  dispatch_async(dispatch_get_main_queue(),^{ \
136  ImplNSAppPostEvent( AquaSalInstance::YieldWakeupEvent, NO ); \
137  }); \
138  { \
139  std::unique_lock<std::mutex> g(aMutex->m_runInMainMutex); \
140  aMutex->m_aResultCondition.wait( \
141  g, [&aMutex]() { return aMutex->m_resultReady; }); \
142  aMutex->m_resultReady = false; \
143  } \
144  return std::move( aMutex->m_aResult.member ); \
145  }
146 
151 #define OSX_INST_RUNINMAIN( command ) \
152  OSX_RUNINMAIN( this, command )
153 
154 #define OSX_INST_RUNINMAIN_POINTER( command, type ) \
155  OSX_RUNINMAIN_POINTER( this, command, type )
156 
157 #define OSX_INST_RUNINMAIN_UNION( command, member ) \
158  OSX_RUNINMAIN_UNION( this, command, member )
159 
164 #define OSX_SALDATA_RUNINMAIN( command ) \
165  OSX_RUNINMAIN( GetSalData()->mpInstance, command )
166 
167 #define OSX_SALDATA_RUNINMAIN_POINTER( command, type ) \
168  OSX_RUNINMAIN_POINTER( GetSalData()->mpInstance, command, type )
169 
170 #define OSX_SALDATA_RUNINMAIN_UNION( command, member ) \
171  OSX_RUNINMAIN_UNION( GetSalData()->mpInstance, command, member )
172 
173 #endif // INCLUDED_VCL_INC_OSX_RUNINMAIN_HXX
174 
175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Runs a command in the main thread.
Definition: runinmain.hxx:51
struct SalFrame::SalPointerState state
Definition: runinmain.hxx:55