ignoreSignalsInThread()

This commit is contained in:
Ștefan Talpalaru 2020-06-21 01:32:13 +02:00
parent f85c8303ee
commit 66e2dc7ba3
No known key found for this signature in database
GPG Key ID: CBF7934204F1B6F9
2 changed files with 49 additions and 3 deletions

View File

@ -1,4 +1,14 @@
import nimcrypto/hash, hashes, stew/byteutils, eth_types, metrics
# Copyright (c) 2019-2020 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
import nimcrypto/hash, hashes, stew/byteutils, eth_types, metrics, os
when defined(posix):
import posix
export metrics
@ -10,5 +20,33 @@ proc parseAddress*(hexString: string): EthAddress =
proc `$`*(a: EthAddress): string =
a.toHex()
# Block all/most signals in the current thread, so we don't interfere with regular signal
# handling elsewhere.
proc ignoreSignalsInThread*() =
when defined(posix):
var signalMask, oldSignalMask: Sigset
# sigprocmask() doesn't work on macOS, for multithreaded programs
if sigfillset(signalMask) != 0:
echo osErrorMsg(osLastError())
quit(QuitFailure)
when defined(boehmgc):
# Turns out Boehm GC needs some signals to deal with threads:
# https://www.hboehm.info/gc/debugging.html
const
SIGPWR = 30
SIGXCPU = 24
SIGSEGV = 11
SIGBUS = 7
if sigdelset(signalMask, SIGPWR) != 0 or
sigdelset(signalMask, SIGXCPU) != 0 or
sigdelset(signalMask, SIGSEGV) != 0 or
sigdelset(signalMask, SIGBUS) != 0:
echo osErrorMsg(osLastError())
quit(QuitFailure)
if pthread_sigmask(SIG_BLOCK, signalMask, oldSignalMask) != 0:
echo osErrorMsg(osLastError())
quit(QuitFailure)
declarePublicGauge connected_peers, "number of peers in the pool"

View File

@ -1,4 +1,4 @@
# Copyright (c) 2019 Status Research & Development GmbH
# Copyright (c) 2019-2020 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
@ -9,7 +9,8 @@
import
options, os, strutils, times,
stew/results, nat_traversal/[miniupnpc, natpmp],
chronicles, json_serialization/std/net
chronicles, json_serialization/std/net,
eth/common/utils
type
NatStrategy* = enum
@ -152,6 +153,7 @@ var
natCloseChan: Channel[bool]
proc repeatPortMapping(args: PortMappingArgs) {.thread.} =
ignoreSignalsInThread()
let
(tcpPort, udpPort, description) = args
interval = initDuration(seconds = PORT_MAPPING_INTERVAL)
@ -180,11 +182,17 @@ proc repeatPortMapping(args: PortMappingArgs) {.thread.} =
proc stopNatThread() {.noconv.} =
# stop the thread
natCloseChan.send(true)
natThread.joinThread()
natCloseChan.close()
# delete our port mappings
# FIXME: if the initial port mapping failed because it already existed for the
# required external port, we should not delete it. It might have been set up
# by another program.
# In Windows, a new thread is created for the signal handler, so we need to
# initialise our threadvars again.
let ipres = getExternalIP(strategy, quiet = true)