loom

Форк
0
/
InterprocessCommunication.cpp 
114 строк · 2.8 Кб
1
/**
2
 * @file InterprocessCommunication.cpp
3
 * @author your name (you@domain.com)
4
 * @brief 
5
 * @version 0.1
6
 * @date 2024-08-02
7
 * 
8
 * @copyright Copyright (c) 2024
9
 * 
10
 */
11

12
#include "simodo/messaging/InterprocessCommunication.h"
13

14
#ifdef CROSS_WIN
15
#include <boost/process/windows.hpp>
16
#endif
17

18
namespace simodo::messaging
19
{
20
    InterprocessCommunication::InterprocessCommunication(
21
                        std::string process_path, 
22
                        std::vector<std::string> process_args)
23
        : _process_path(process_path)
24
        , _process_args(process_args)
25
    {
26
    }
27

28
    InterprocessCommunication::~InterprocessCommunication()
29
    {
30
        close();
31
    }
32

33
    bool InterprocessCommunication::open(std::function<void(std::string &)> receiver) 
34
    {
35
        if (_opened)
36
            return true;
37

38
        try {
39
            _server = std::make_unique<bp::child>(
40
                                _process_path
41
                                , _process_args
42
                                , bp::std_in < _os
43
                                , bp::std_out > _is
44
    #ifdef CROSS_WIN
45
                                , bp::windows::hide
46
    #endif
47
                                , bp::on_exit([&](auto...)
48
                                {
49
                                    _is.close();
50
                                    _os.close();
51
                                    _opened = false;
52
                                    if (_receiver) {
53
                                        std::string s;
54
                                        _receiver(s);
55
                                    }
56
                                }
57
                                ));
58

59
            _opened = true;
60
        }
61
        catch(const std::exception& e) {
62
            _last_error = e.what();
63
            _server.reset();
64
        }
65

66
        if (!_opened)
67
            return false;
68

69
        _receiver = receiver;
70

71
        if (_receiver)
72
            _response_thread = std::make_unique<std::thread>(&InterprocessCommunication::response_listener, this);
73

74
        return true;
75
    }
76

77
    void InterprocessCommunication::close() 
78
    {
79
        if (!_opened)
80
            return;
81

82
        _opened = false;
83
        _server.reset();
84

85
        if (_response_thread)
86
            _response_thread->join();
87
    }
88

89
    void InterprocessCommunication::send(const std::string & s)
90
    {
91
        if (_server->running() && _os.good()) {
92
            _os << s << "\n";
93
            _os.flush();
94
        }
95
    }
96

97
    /**************************************************************************
98
     * private
99
     **************************************************************************/
100

101
    void InterprocessCommunication::response_listener()
102
    {
103
        assert(_receiver);
104

105
        while(_opened && _is.good()) {
106
            std::string line;
107

108
            if (std::getline(_is,line))
109
                _receiver(line);
110
        }
111
    }
112

113

114
}
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.