MDEV-34534 main.plugin_load(daemon_example) - AddressSanitizer: Joining already joined thread, aborting
Joining with a thread that has previously been joined results in undefined behavior. This example plugin performs the same join to the same thread a few lines later. ASAN keeps track of this and fails. Make the behaviour defined by joining only once. Thanks Vladislav Vaintroub for looking up the behaviour. While here; * init/deinit function argument was actually used. * correct code comments * attribute define not needed Thanks Marko Mäkelä for review and suggesting other fixes.
This commit is contained in:
parent
b65504b8db
commit
1d6502b4f4
@ -26,14 +26,6 @@
|
|||||||
#include "m_string.h" // strlen
|
#include "m_string.h" // strlen
|
||||||
#include "sql_plugin.h" // st_plugin_int
|
#include "sql_plugin.h" // st_plugin_int
|
||||||
|
|
||||||
/*
|
|
||||||
Disable __attribute__() on non-gcc compilers.
|
|
||||||
*/
|
|
||||||
#if !defined(__attribute__) && !defined(__GNUC__)
|
|
||||||
#define __attribute__(A)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define HEART_STRING_BUFFER 100
|
#define HEART_STRING_BUFFER 100
|
||||||
|
|
||||||
struct mysql_heartbeat_context
|
struct mysql_heartbeat_context
|
||||||
@ -77,14 +69,14 @@ pthread_handler_t mysql_heartbeat(void *p)
|
|||||||
daemon_example_plugin_init()
|
daemon_example_plugin_init()
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Starts up heartbeatbeat thread
|
Starts up heartbeat thread (mysql_heartbeat)
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
0 success
|
0 success
|
||||||
1 failure (cannot happen)
|
1 failure (cannot happen)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int daemon_example_plugin_init(void *p __attribute__ ((unused)))
|
static int daemon_example_plugin_init(void *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
DBUG_ENTER("daemon_example_plugin_init");
|
DBUG_ENTER("daemon_example_plugin_init");
|
||||||
@ -150,7 +142,7 @@ static int daemon_example_plugin_init(void *p __attribute__ ((unused)))
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
|
static int daemon_example_plugin_deinit(void *p)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("daemon_example_plugin_deinit");
|
DBUG_ENTER("daemon_example_plugin_deinit");
|
||||||
char buffer[HEART_STRING_BUFFER];
|
char buffer[HEART_STRING_BUFFER];
|
||||||
@ -162,6 +154,10 @@ static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
|
|||||||
|
|
||||||
pthread_cancel(con->heartbeat_thread);
|
pthread_cancel(con->heartbeat_thread);
|
||||||
pthread_join(con->heartbeat_thread, NULL);
|
pthread_join(con->heartbeat_thread, NULL);
|
||||||
|
/*
|
||||||
|
As thread is joined, we can close the file it writes to and
|
||||||
|
free the memory it uses.
|
||||||
|
*/
|
||||||
|
|
||||||
localtime_r(&result, &tm_tmp);
|
localtime_r(&result, &tm_tmp);
|
||||||
my_snprintf(buffer, sizeof(buffer),
|
my_snprintf(buffer, sizeof(buffer),
|
||||||
@ -174,12 +170,6 @@ static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
|
|||||||
tm_tmp.tm_sec);
|
tm_tmp.tm_sec);
|
||||||
my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
|
my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
|
||||||
|
|
||||||
/*
|
|
||||||
Need to wait for the hearbeat thread to terminate before closing
|
|
||||||
the file it writes to and freeing the memory it uses.
|
|
||||||
*/
|
|
||||||
pthread_join(con->heartbeat_thread, NULL);
|
|
||||||
|
|
||||||
my_close(con->heartbeat_file, MYF(0));
|
my_close(con->heartbeat_file, MYF(0));
|
||||||
|
|
||||||
my_free(con);
|
my_free(con);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user