1/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights
2 reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
17#include <my_global.h>
18#include <sql_priv.h>
19#include <stdlib.h>
20#include <ctype.h>
21#include <mysql_version.h>
22#include <mysql/plugin.h>
23#include <my_dir.h>
24#include "my_pthread.h" // pthread_handler_t
25#include "my_sys.h" // my_write, my_malloc
26#include "m_string.h" // strlen
27#include "sql_plugin.h" // st_plugin_int
28
29/*
30 Disable __attribute__() on non-gcc compilers.
31*/
32#if !defined(__attribute__) && !defined(__GNUC__)
33#define __attribute__(A)
34#endif
35
36
37#define HEART_STRING_BUFFER 100
38
39struct mysql_heartbeat_context
40{
41 pthread_t heartbeat_thread;
42 File heartbeat_file;
43};
44
45pthread_handler_t mysql_heartbeat(void *p)
46{
47 DBUG_ENTER("mysql_heartbeat");
48 struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p;
49 char buffer[HEART_STRING_BUFFER];
50 time_t result;
51 struct tm tm_tmp;
52
53 while(1)
54 {
55 sleep(5);
56
57 result= time(NULL);
58 localtime_r(&result, &tm_tmp);
59 my_snprintf(buffer, sizeof(buffer),
60 "Heartbeat at %02d%02d%02d %2d:%02d:%02d\n",
61 tm_tmp.tm_year % 100,
62 tm_tmp.tm_mon+1,
63 tm_tmp.tm_mday,
64 tm_tmp.tm_hour,
65 tm_tmp.tm_min,
66 tm_tmp.tm_sec);
67 my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
68 }
69
70 DBUG_RETURN(0);
71}
72
73/*
74 Initialize the daemon example at server start or plugin installation.
75
76 SYNOPSIS
77 daemon_example_plugin_init()
78
79 DESCRIPTION
80 Starts up heartbeatbeat thread
81
82 RETURN VALUE
83 0 success
84 1 failure (cannot happen)
85*/
86
87static int daemon_example_plugin_init(void *p __attribute__ ((unused)))
88{
89
90 DBUG_ENTER("daemon_example_plugin_init");
91 struct mysql_heartbeat_context *con;
92 pthread_attr_t attr; /* Thread attributes */
93 char heartbeat_filename[FN_REFLEN];
94 char buffer[HEART_STRING_BUFFER];
95 time_t result= time(NULL);
96 struct tm tm_tmp;
97
98 struct st_plugin_int *plugin= (struct st_plugin_int *)p;
99
100 con= (struct mysql_heartbeat_context *)
101 my_malloc(sizeof(struct mysql_heartbeat_context), MYF(0));
102
103 fn_format(heartbeat_filename, "mysql-heartbeat", "", ".log",
104 MY_REPLACE_EXT | MY_UNPACK_FILENAME);
105 unlink(heartbeat_filename);
106 con->heartbeat_file= my_open(heartbeat_filename, O_CREAT|O_RDWR, MYF(0));
107
108 /*
109 No threads exist at this point in time, so this is thread safe.
110 */
111 localtime_r(&result, &tm_tmp);
112 my_snprintf(buffer, sizeof(buffer),
113 "Starting up at %02d%02d%02d %2d:%02d:%02d\n",
114 tm_tmp.tm_year % 100,
115 tm_tmp.tm_mon+1,
116 tm_tmp.tm_mday,
117 tm_tmp.tm_hour,
118 tm_tmp.tm_min,
119 tm_tmp.tm_sec);
120 my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
121
122 pthread_attr_init(&attr);
123 pthread_attr_setdetachstate(&attr,
124 PTHREAD_CREATE_JOINABLE);
125
126
127 /* now create the thread */
128 if (pthread_create(&con->heartbeat_thread, &attr, mysql_heartbeat,
129 (void *)con) != 0)
130 {
131 fprintf(stderr,"Could not create heartbeat thread!\n");
132 DBUG_RETURN(1);
133 }
134 plugin->data= (void *)con;
135
136 DBUG_RETURN(0);
137}
138
139
140/*
141 Terminate the daemon example at server shutdown or plugin deinstallation.
142
143 SYNOPSIS
144 daemon_example_plugin_deinit()
145 Does nothing.
146
147 RETURN VALUE
148 0 success
149 1 failure (cannot happen)
150
151*/
152
153static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
154{
155 DBUG_ENTER("daemon_example_plugin_deinit");
156 char buffer[HEART_STRING_BUFFER];
157 struct st_plugin_int *plugin= (struct st_plugin_int *)p;
158 struct mysql_heartbeat_context *con=
159 (struct mysql_heartbeat_context *)plugin->data;
160 time_t result= time(NULL);
161 struct tm tm_tmp;
162
163 pthread_cancel(con->heartbeat_thread);
164 pthread_join(con->heartbeat_thread, NULL);
165
166 localtime_r(&result, &tm_tmp);
167 my_snprintf(buffer, sizeof(buffer),
168 "Shutting down at %02d%02d%02d %2d:%02d:%02d\n",
169 tm_tmp.tm_year % 100,
170 tm_tmp.tm_mon+1,
171 tm_tmp.tm_mday,
172 tm_tmp.tm_hour,
173 tm_tmp.tm_min,
174 tm_tmp.tm_sec);
175 my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
176
177 /*
178 Need to wait for the hearbeat thread to terminate before closing
179 the file it writes to and freeing the memory it uses.
180 */
181 pthread_join(con->heartbeat_thread, NULL);
182
183 my_close(con->heartbeat_file, MYF(0));
184
185 my_free(con);
186
187 DBUG_RETURN(0);
188}
189
190
191struct st_mysql_daemon daemon_example_plugin=
192{ MYSQL_DAEMON_INTERFACE_VERSION };
193
194/*
195 Plugin library descriptor
196*/
197
198maria_declare_plugin(daemon_example)
199{
200 MYSQL_DAEMON_PLUGIN,
201 &daemon_example_plugin,
202 "daemon_example",
203 "Brian Aker",
204 "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log",
205 PLUGIN_LICENSE_GPL,
206 daemon_example_plugin_init, /* Plugin Init */
207 daemon_example_plugin_deinit, /* Plugin Deinit */
208 0x0100 /* 1.0 */,
209 NULL, /* status variables */
210 NULL, /* system variables */
211 "1.0", /* string version */
212 MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* maturity */
213}
214maria_declare_plugin_end;
215