2525#include  < unistd.h> 
2626
2727#include  < libssh/sftp.h> 
28- #include  < multipass/auto_join_thread .h> 
28+ #include  < multipass/timer .h> 
2929
3030namespace  mp  =  multipass;
3131
@@ -158,6 +158,25 @@ int mp::platform::symlink_attr_from(const char* path, sftp_attributes_struct* at
158158    return  0 ;
159159}
160160
161+ mp::platform::SignalWrapper::SignalWrapper (const  PrivatePass& pass) noexcept 
162+ : Singleton(pass){}
163+ 
164+ 
165+ int  mp::platform::SignalWrapper::mask_signals (int  how, const  sigset_t * sigset, sigset_t * old_set) const 
166+ {
167+     return  pthread_sigmask (how, sigset, old_set);
168+ }
169+ 
170+ int  mp::platform::SignalWrapper::send (pthread_t  target, int  signal) const 
171+ {
172+     return  pthread_kill (target, signal);
173+ }
174+ 
175+ int  mp::platform::SignalWrapper::wait (const  sigset_t & sigset, int & got) const 
176+ {
177+     return  sigwait (std::addressof (sigset), std::addressof (got));
178+ }
179+ 
161180sigset_t  mp::platform::make_sigset (const  std::vector<int >& sigs)
162181{
163182    sigset_t  sigset;
@@ -172,7 +191,7 @@ sigset_t mp::platform::make_sigset(const std::vector<int>& sigs)
172191sigset_t  mp::platform::make_and_block_signals (const  std::vector<int >& sigs)
173192{
174193    auto  sigset{make_sigset (sigs)};
175-     pthread_sigmask (SIG_BLOCK, &sigset, nullptr );
194+     MP_POSIX_SIGNAL. mask_signals (SIG_BLOCK, &sigset, nullptr );
176195    return  sigset;
177196}
178197
@@ -188,34 +207,25 @@ std::function<std::optional<int>(const std::function<bool()>&)> mp::platform::ma
188207{
189208    return  [sigset = make_and_block_signals ({SIGQUIT, SIGTERM, SIGHUP, SIGUSR2}),
190209            period](const  std::function<bool ()>& condition) -> std::optional<int > {
191-         std::mutex sig_mtx;
192-         std::condition_variable sig_cv;
193-         int  sig = SIGUSR2;
194- 
195-         //  A signal generator that triggers after `timeout`
196-         AutoJoinThread signaler ([&sig_mtx, &sig_cv, &sig, &period, signalee = pthread_self ()] {
197-             std::unique_lock lock (sig_mtx);
198-             while  (!sig_cv.wait_for (lock, period, [&sig] { return  sig != SIGUSR2; }))
199-             {
200-                 pthread_kill (signalee, SIGUSR2);
201-             }
202-         });
210+ 
211+         //  create a timer to periodically send SIGUSR2
212+         utils::Timer signal_generator{period, [signalee = pthread_self ()] {
213+             MP_POSIX_SIGNAL.send (signalee, SIGUSR2);
214+         }};
203215
204216        //  wait on signals and condition
205217        int  latest_signal = SIGUSR2;
206218        while  (latest_signal == SIGUSR2 && condition ())
207219        {
220+             signal_generator.start ();
221+ 
208222            //  can't use sigtimedwait since macOS doesn't support it
209-             sigwait (& sigset, & latest_signal);
223+             MP_POSIX_SIGNAL. wait ( sigset, latest_signal);
210224        }
211225
212-         { //  set `sig` to something other than SIGUSR2 so `signaler` knows to exit
213-             std::lock_guard lock (sig_mtx);
214-             sig = latest_signal == SIGUSR2 ? 0  : latest_signal;
215-         }
216-         sig_cv.notify_all ();
226+         signal_generator.stop ();
217227
218-         //  if `sig ` is 0  then we know we're exiting because  condition() was  false
219-         return  sig  ? std::make_optional  (sig)  : std::nullopt ;
228+         //  if `latest_signal ` is SIGUSR2  then we know ` condition()` is  false
229+         return  latest_signal == SIGUSR2  ? std::nullopt  : std::make_optional  (latest_signal) ;
220230    };
221231}
0 commit comments