Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit bitcoind immediately on shutdown instead of 200ms later #10125

Closed

Conversation

TheBlueMatt
Copy link
Contributor

This is especially useful for AbortNode(). I have no idea how to make the equivalent change in bitcoin-qt, maybe @jonasschnelli can add some signal thing for it?

Copy link
Contributor

@JeremyRubin JeremyRubin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utack, no reason to sleep.

src/init.cpp Outdated

void StartShutdown()
{
fRequestShutdown = true;
std::unique_lock<std::mutex> lockShutdownWait(mutexShutdownWait);
cvShutdownWait.notify_all();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this get mirrored to HandleSIGTERM?

src/init.cpp Outdated
}
bool ShutdownRequested()
{
return fRequestShutdown;
}

void WaitForShutdownRequested() {
std::unique_lock<std::mutex> lockShutdownWait(mutexShutdownWait);
cvShutdownWait.wait(lockShutdownWait, []() { return ShutdownRequested(); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really worth doing, but you could also wrap this in an initial if (!ShutdownRequested() so as not to take the lock.

src/init.cpp Outdated

void StartShutdown()
{
fRequestShutdown = true;
std::unique_lock<std::mutex> lockShutdownWait(mutexShutdownWait);
cvShutdownWait.notify_all();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this is allowed in signal handlers? From what I remember that is the reason for the circuitous polling. If not we need a special path for signals and one for the rest (like AbortNode).

@TheBlueMatt
Copy link
Contributor Author

Made the wait still wake up every 200ms to address the sigTERM issue.

@jonasschnelli
Copy link
Contributor

The QT part would require something like this (though incomplete): jonasschnelli@4ed60ff

@TheBlueMatt
Copy link
Contributor Author

@jonasschnelli is there a way to do that without adding a new thread? Some kind of signal in addition to the current polling method?

@laanwj
Copy link
Member

laanwj commented Mar 31, 2017

Yes, you could use a signal on the uiInterface that sends a Qt signal, similar to how the other signals for ClientModel work.

@jonasschnelli
Copy link
Contributor

Yes, you could use a signal on the uiInterface that sends a Qt signal, similar to how the other signals for ClientModel work.

Yes. That would be much better. I'll write a commit soon.

@laanwj
Copy link
Member

laanwj commented Mar 31, 2017

Yes. That would be much better. I'll write a commit soon.

Great!
I guess the uiInterface signal could be called in WaitForShutdown after the wait loop exits. This means we don't need to do any polling of fRequestShutdown ourselves in the GUI anymore. Much cleaner indeed.
never mind: we don't use WaitForShutdown when the GUI runs. Need to keep the polling for the same reason WaitForShutdown does, UNIX signal handling.

src/init.cpp Outdated

void StartShutdown()
{
fRequestShutdown = true;
std::unique_lock<std::mutex> lockShutdownWait(mutexShutdownWait);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should acquire the lock before setting fRequestShutdown?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could, doesnt matter though because fRequestShutdown is atomic.

@TheBlueMatt
Copy link
Contributor Author

TheBlueMatt commented Mar 31, 2017

Honestly I have no idea why travis is failing here. If you remove the cv notify_all() it works fine, the second you add it back travis hangs and I cannot reproduce the issue locally.

@@ -125,16 +125,27 @@ static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";

std::atomic<bool> fRequestShutdown(false);
std::atomic<bool> fDumpMempoolLater(false);
static std::mutex mutexShutdownWait;
static std::condition_variable cvShutdownWait;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a CThreadInterrupt here instead? This is exactly what it's meant to be used for :)

@jnewbery
Copy link
Contributor

I did a run of travis with the create_cache.py script commented out (so the test_runner script just launches the test cases immediately) and the tests seem to fail intermittently. Travis logs here: https://travis-ci.org/jnewbery/bitcoin/builds/217310887

Failure is:

raceback (most recent call last):
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/authproxy.py", line 125, in _request
    return self._get_response()
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/authproxy.py", line 167, in _get_response
    http_response = self.__conn.getresponse()
  File "/usr/lib/python3.4/http/client.py", line 1208, in getresponse
    response.begin()
  File "/usr/lib/python3.4/http/client.py", line 380, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python3.4/http/client.py", line 350, in _read_status
    raise BadStatusLine(line)
http.client.BadStatusLine: ''
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/test_framework.py", line 151, in main
    self.run_test()
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/fundrawtransaction.py", line 449, in run_test
    self.nodes[1].encryptwallet("test")
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/coverage.py", line 46, in __call__
    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/authproxy.py", line 151, in __call__
    response = self._request('POST', self.__url.path, postdata.encode('utf-8'))
  File "/home/travis/build/jnewbery/bitcoin/build/bitcoin-x86_64-unknown-linux-gnu/test/functional/test_framework/authproxy.py", line 129, in _request
    self.__conn.request(method, path, postdata, headers)
  File "/usr/lib/python3.4/http/client.py", line 1125, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.4/http/client.py", line 1163, in _send_request
    self.endheaders(body)
  File "/usr/lib/python3.4/http/client.py", line 1121, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python3.4/http/client.py", line 951, in _send_output
    self.send(msg)
  File "/usr/lib/python3.4/http/client.py", line 886, in send
    self.connect()
  File "/usr/lib/python3.4/http/client.py", line 863, in connect
    self.timeout, self.source_address)
  File "/usr/lib/python3.4/socket.py", line 512, in create_connection
    raise err
  File "/usr/lib/python3.4/socket.py", line 503, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

This reproduces locally for me. Seems like there's a race between bitcoind shutting down and responding to the 'stop' RPC.

@jonasschnelli
Copy link
Contributor

Maybe this Qt approach makes more sense: jonasschnelli@d356512

@TheBlueMatt
Copy link
Contributor Author

TheBlueMatt commented Apr 1, 2017 via email

@jonasschnelli
Copy link
Contributor

@TheBlueMatt: if you want to execute the function in the main GUI thread, add another Qt signal and use Q_EMIT (emit it from the uiInterface Signal listener).

@TheBlueMatt
Copy link
Contributor Author

Closing. I spent some time debugging further but dont think its a huge deal to sleep 200ms and it looks annoying to fix, at best. Someone else is welcome to pick this up if they feel so inclined.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants