Repository: apple/swift
File: stdlib/public/runtime/CrashHandlerLinux.cpp (C++)

Code before:
          ++pending;
        } else {
          // try another time to see if we can signal via the outer loop...
          ++waitingToSignal;
          warn("swift-runtime: failed to suspend thread ");
          warn(dp->d_name);
          warn(" retrying...\n");
        }
      }
    }

    // If we find no new threads, we're done
    if (!pending && !waitingToSignal)
      break;

    // Wait for the threads to suspend
    struct timespec timeout = { 2, 0 };
    if (waitingToSignal) {
      timeout = (struct timespec){ 0, 10000000 };
    }

    wait_paused(paused + pending, &timeout);
  } while (max_loops--);

  if (waitingToSignal) {
    warn("failed to suspend thread while processing a crash; "
      "backtraces will be missing information\n");
  }

  // Close the directory
  close(fd);

  // Finally, reset the signal handlers
  sigaction(SIGPROF, &sa_old_prof, NULL);
  sigaction(SIGUSR1, &sa_old_usr1, NULL);
  sigaction(SIGUSR2, &sa_old_usr2, NULL);
}

void
resume_other_threads()
{
  // All we need to do here is release the lock.
  release_thread_lock();
}

// .. Locking ..................................................................

/* We use a futex to block the threads; we also use one to let us work out
   when all the threads we've asked to pause have actually paused. */
int
futex(uint32_t *uaddr, int futex_op, uint32_t val,

Review comment (bug):
```suggestion
    warn("swift-runtime: failed to suspend thread while processing a crash; "
```

Code after:
      break;

    if (!pending) {
      // we are not waiting for any thread to pause, but we haven't exited
      // so waitingToSignal > 0 and pending == 0
      // when we are unable to get a suitable signal for at least one thread,
      // a common cause is glibc masking signals temporarily, for things like
      // pthread creation/termination, try a short pause, then we'll try again
      // on the next iteration
      struct timespec shortDelay;
      shortDelay.tv_sec = 0;
      shortDelay.tv_nsec = 10000000;
      nanosleep(&shortDelay, NULL);
    }

    // Wait for the threads to suspend
    struct timespec timeout = { 2, 0 };
    wait_paused(paused + pending, &timeout);
  } while (max_loops--);

  if (waitingToSignal) {
    warn("swift-runtime: failed to suspend thread while processing a crash; "
      "backtraces will be missing information\n");
  }

  // Close the directory
  close(fd);

  // Finally, reset the signal handlers
  sigaction(SIGPROF, &sa_old_prof, NULL);
  sigaction(SIGUSR1, &sa_old_usr1, NULL);
  sigaction(SIGUSR2, &sa_old_usr2, NULL);
}

void
resume_other_threads()
{
  // All we need to do here is release the lock.
  release_thread_lock();
}

// .. Locking ..................................................................

/* We use a futex to block the threads; we also use one to let us work out
   when all the threads we've asked to pause have actually paused. */
int
futex(uint32_t *uaddr, int futex_op, uint32_t val,
      const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3)
{
  return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}