140 lines
3.2 KiB
C++
140 lines
3.2 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include "share/ob_define.h"
|
|
/*
|
|
//signal function should not call I/O function and nother non-reentrant functions
|
|
//this test would have a dead lock. Because localtime_r have a lock. When signal interrupt
|
|
//occurs, if the main function get the lock and had not released it, the dead lock produced.
|
|
void handler(int signum)
|
|
{
|
|
char result[100];
|
|
time_t now;
|
|
struct tm time1;
|
|
now = time(NULL);
|
|
localtime_r(&now, &time1);
|
|
strftime(result, 100, "%T", &time1);
|
|
printf("At %s, user pressed Ctrl-C\n", result);
|
|
}
|
|
|
|
int main (void)
|
|
{
|
|
time_t now;
|
|
struct tm ltime;
|
|
|
|
if (signal(SIGINT, handler) == SIG_IGN)
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
now = time(NULL);
|
|
while(1) {
|
|
localtime_r(&now, <ime);
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
namespace test {
|
|
|
|
bool g_run_test = false;
|
|
void signal_handler(int signum)
|
|
{
|
|
printf("singal num: %d", signum);
|
|
char result[100];
|
|
time_t now;
|
|
struct tm time1;
|
|
now = time(NULL);
|
|
localtime_r(&now, &time1);
|
|
strftime(result, 100, "%T", &time1);
|
|
printf("At %s, user pressed Ctrl-C\n", result);
|
|
}
|
|
|
|
class ObSignalDealThread: public share::ObThreadPool
|
|
{
|
|
public:
|
|
virtual void run1();
|
|
};
|
|
|
|
class ObSignalTest: public ::testing::Test
|
|
{
|
|
public:
|
|
void run_test();
|
|
protected:
|
|
ObSignalDealThread signal_deal_thread_;
|
|
};
|
|
|
|
void ObSignalDealThread::run(obsys::CThread *thread, void *arg)
|
|
{
|
|
|
|
UNUSED(arg);
|
|
sigset_t waitset;
|
|
int signum;
|
|
sigemptyset(&waitset);
|
|
sigaddset(&waitset, SIGINT);
|
|
struct timespec timeout = {1, 0};
|
|
while (!has_set_stop()) {
|
|
if ( -1 == (signum = sigtimedwait(&waitset, NULL, &timeout))) {
|
|
//do not log error, because timeout will also return -1.
|
|
printf("time out or error, errno=%d, errmsg=%m\n", errno);
|
|
} else {
|
|
printf("sigwaitinfo() fetch the signal: %d\n", signum);
|
|
signal_handler(signum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObSignalTest::run_test()
|
|
{
|
|
if (g_run_test) {
|
|
//first sigmask in main thread
|
|
sigset_t bset, oset;
|
|
sigemptyset(&bset);
|
|
sigaddset(&bset, SIGINT);
|
|
if (pthread_sigmask(SIG_BLOCK, &bset, &oset) != 0)
|
|
printf("!! Set pthread mask failed\n");
|
|
|
|
//second start signal deal thread
|
|
signal_deal_thread_.start();
|
|
|
|
//loop call localtime_r
|
|
time_t now;
|
|
struct tm ltime;
|
|
now = time(NULL);
|
|
while(1) {
|
|
localtime_r(&now, <ime);
|
|
}
|
|
signal_deal_thread_.wait();
|
|
}
|
|
}
|
|
|
|
TEST_F(ObSignalTest, signal_test)
|
|
{
|
|
run_test();
|
|
}
|
|
}
|
|
|
|
//use ./test_signal_handle run
|
|
int main(int argc, char **argv)
|
|
{
|
|
::testing::InitGoogleTest(&argc,argv);
|
|
if (argc >= 2) {
|
|
if (strcmp("run", argv[1]) ==0) {
|
|
::test::g_run_test = true;
|
|
}
|
|
}
|
|
return RUN_ALL_TESTS();
|
|
}
|