Вопрос про исключение abi::__forced_unwind.
Почему в Linux оно есть, а в FreeBSD, например, нет?
Вот пример кода. Что бы не получать «FATAL: exception not rethrown» приходится собирать с условной компиляцией.
Как это обойти и из-за чего оно вообще возникает?
#include <iostream>
#include <functional>
#include <vector>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#ifdef __linux__
#include <cxxabi.h>
#define __catch_all__ catch (abi::__forced_unwind&) { throw; } catch (...)
#else
#define __catch_all__ catch (...)
#endif
bool test_proc(const size_t &nom)
{
std::cerr << nom;
sleep(1);
return true;
}
class threads
{
public:
typedef
struct
{
pthread_t pid;
size_t nom;
}
item_type;
typedef
std::function<bool(const size_t &nom)>
proc_type;
private:
static std::vector<item_type> items;
static proc_type proc;
static void *inner_proc(void *data);
static void interrupter(int signum);
public:
static void start
(const proc_type &proc, const size_t &count);
static void stop(void);
};
threads::proc_type threads::proc = threads::proc_type();
std::vector<threads::item_type> threads::items = std::vector<threads::item_type>();
void *threads::inner_proc(void *data)
{
if (threads::proc)
{
auto item = (threads::item_type *) data;
for (;;)
try
{
threads::proc(item->nom);
}
__catch_all__
{
}
}
return NULL;
}
void threads::interrupter(int signum)
{
signum = signum;
threads::stop();
}
void threads::start(const proc_type &proc, const size_t &count)
{
threads::proc = proc;
threads::items.resize(count);
if (!count) return;
size_t nom = 0;
for (auto &i : threads::items)
{
i.nom = nom;
pthread_create(&i.pid, NULL, threads::inner_proc, &i);
nom++;
}
static struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = threads::interrupter;
sigaction(SIGINT, &sa, NULL);
pthread_join(threads::items[0].pid, NULL);
}
void threads::stop(void)
{
auto nom = threads::items.size();
while (nom)
{
nom--;
pthread_cancel(threads::items[nom].pid);
}
threads::items.resize(0);
}
int main(void)
{
std::cout << "Start" << std::endl;
threads::start(test_proc, 3);
std::cout << "Stop" << std::endl;
return EXIT_SUCCESS;
}