make Mysql2::Client destructor safely non-blocking
Since sending a QUIT message to the MySQL server is more of a formality than a hard requirement in a TCP-based protocol, we'll just fire-and-forget the message to avoid any chance of blocking the interpreter during the GC finalizer phase. Since the socket will be closed immediately afterwards, there's no long-term side-effects from making the socket non-blocking. We do this instead of using rb_thread_blocking_region because the GVL is already destroyed by the time the ObjectSpace finalizers are called under 1.9.
This commit is contained in:
parent
46021b9351
commit
ec00873181
@ -187,10 +187,23 @@ static void rb_mysql_client_free(void * ptr) {
|
||||
|
||||
if (client->client) {
|
||||
/*
|
||||
* this may send a "QUIT" message to the server and thus block
|
||||
* on the socket write, users are encouraged to close this manually
|
||||
* to avoid this behavior
|
||||
* we'll send a QUIT message to the server, but that message is more of a
|
||||
* formality than a hard requirement since the socket is getting shutdown
|
||||
* anyways, so ensure the socket write does not block our interpreter
|
||||
*/
|
||||
int fd = client->client->net.fd;
|
||||
int flags;
|
||||
|
||||
if (fd >= 0) {
|
||||
/*
|
||||
* if the socket is dead we have no chance of blocking,
|
||||
* so ignore any potential fcntl errors since they don't matter
|
||||
*/
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags > 0 && !(flags & O_NONBLOCK))
|
||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
mysql_close(client->client);
|
||||
}
|
||||
xfree(ptr);
|
||||
@ -204,8 +217,8 @@ static VALUE nogvl_close(void * ptr) {
|
||||
/*
|
||||
* Immediately disconnect from the server, normally the garbage collector
|
||||
* will disconnect automatically when a connection is no longer needed.
|
||||
* Explicitly closing this can free up server resources sooner and is
|
||||
* also 100% safe when faced with signals or running multithreaded
|
||||
* Explicitly closing this will free up server resources sooner than waiting
|
||||
* for the garbage collector.
|
||||
*/
|
||||
static VALUE rb_mysql_client_close(VALUE self) {
|
||||
mysql2_client_wrapper *client;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <ruby.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_MYSQL_H
|
||||
#include <mysql.h>
|
||||
|
Loading…
Reference in New Issue
Block a user