pyxcp 0.21.9__cp311-cp311-win_amd64.whl → 0.22.23__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyxcp might be problematic. Click here for more details.
- pyxcp/__init__.py +12 -20
- pyxcp/aml/EtasCANMonitoring.a2l +82 -83
- pyxcp/aml/XCP_Common.aml +0 -1
- pyxcp/aml/XCPonUSB.aml +1 -1
- pyxcp/aml/ifdata_CAN.a2l +0 -1
- pyxcp/aml/ifdata_Eth.a2l +0 -1
- pyxcp/aml/ifdata_Flx.a2l +0 -1
- pyxcp/aml/ifdata_SxI.a2l +0 -1
- pyxcp/aml/ifdata_USB.a2l +0 -1
- pyxcp/asam/types.py +4 -4
- pyxcp/asamkeydll.c +0 -1
- pyxcp/checksum.py +0 -1
- pyxcp/cmdline.py +32 -50
- pyxcp/config/__init__.py +1100 -0
- pyxcp/config/legacy.py +120 -0
- pyxcp/constants.py +12 -13
- pyxcp/cpp_ext/__init__.py +0 -0
- pyxcp/cpp_ext/bin.hpp +104 -0
- pyxcp/cpp_ext/blockmem.hpp +58 -0
- pyxcp/cpp_ext/cpp_ext.cp310-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp311-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp38-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/cpp_ext.cp39-win_amd64.pyd +0 -0
- pyxcp/cpp_ext/daqlist.hpp +200 -0
- pyxcp/cpp_ext/event.hpp +67 -0
- pyxcp/cpp_ext/extension_wrapper.cpp +96 -0
- pyxcp/cpp_ext/helper.hpp +280 -0
- pyxcp/cpp_ext/mcobject.hpp +246 -0
- pyxcp/cpp_ext/tsqueue.hpp +46 -0
- pyxcp/daq_stim/__init__.py +228 -0
- pyxcp/daq_stim/optimize/__init__.py +67 -0
- pyxcp/daq_stim/optimize/binpacking.py +41 -0
- pyxcp/daq_stim/scheduler.cpp +28 -0
- pyxcp/daq_stim/scheduler.hpp +75 -0
- pyxcp/daq_stim/stim.cp310-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp311-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp38-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cp39-win_amd64.pyd +0 -0
- pyxcp/daq_stim/stim.cpp +13 -0
- pyxcp/daq_stim/stim.hpp +604 -0
- pyxcp/daq_stim/stim_wrapper.cpp +48 -0
- pyxcp/dllif.py +21 -18
- pyxcp/errormatrix.py +5 -3
- pyxcp/examples/conf_can.toml +4 -2
- pyxcp/examples/conf_can_vector.json +9 -9
- pyxcp/examples/conf_can_vector.toml +4 -2
- pyxcp/examples/conf_eth.toml +5 -2
- pyxcp/examples/conf_nixnet.json +18 -18
- pyxcp/examples/conf_sxi.json +7 -7
- pyxcp/examples/ex_arrow.py +109 -0
- pyxcp/examples/ex_csv.py +85 -0
- pyxcp/examples/ex_excel.py +95 -0
- pyxcp/examples/ex_mdf.py +124 -0
- pyxcp/examples/ex_sqlite.py +128 -0
- pyxcp/examples/run_daq.py +148 -0
- pyxcp/examples/xcp_policy.py +6 -7
- pyxcp/examples/xcp_read_benchmark.py +8 -6
- pyxcp/examples/xcp_skel.py +0 -2
- pyxcp/examples/xcp_unlock.py +1 -1
- pyxcp/examples/xcp_user_supplied_driver.py +1 -2
- pyxcp/examples/xcphello.py +6 -3
- pyxcp/examples/xcphello_recorder.py +4 -4
- pyxcp/master/__init__.py +1 -2
- pyxcp/master/errorhandler.py +107 -74
- pyxcp/master/master.py +196 -114
- pyxcp/py.typed +0 -0
- pyxcp/recorder/__init__.py +27 -6
- pyxcp/recorder/converter/__init__.py +37 -0
- pyxcp/recorder/lz4.c +129 -51
- pyxcp/recorder/lz4.h +45 -28
- pyxcp/recorder/lz4hc.c +560 -156
- pyxcp/recorder/lz4hc.h +1 -1
- pyxcp/recorder/mio.hpp +721 -767
- pyxcp/recorder/reader.hpp +139 -0
- pyxcp/recorder/reco.py +5 -8
- pyxcp/recorder/rekorder.cp310-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp311-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp38-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cp39-win_amd64.pyd +0 -0
- pyxcp/recorder/rekorder.cpp +18 -22
- pyxcp/recorder/rekorder.hpp +200 -587
- pyxcp/recorder/setup.py +11 -10
- pyxcp/recorder/test_reko.py +2 -3
- pyxcp/recorder/unfolder.hpp +1332 -0
- pyxcp/recorder/wrap.cpp +171 -9
- pyxcp/recorder/writer.hpp +302 -0
- pyxcp/scripts/pyxcp_probe_can_drivers.py +0 -2
- pyxcp/scripts/xcp_examples.py +64 -0
- pyxcp/scripts/xcp_fetch_a2l.py +15 -10
- pyxcp/scripts/xcp_id_scanner.py +2 -6
- pyxcp/scripts/xcp_info.py +101 -63
- pyxcp/scripts/xcp_profile.py +27 -0
- pyxcp/stim/__init__.py +0 -0
- pyxcp/tests/test_asam_types.py +2 -2
- pyxcp/tests/test_binpacking.py +186 -0
- pyxcp/tests/test_can.py +1132 -38
- pyxcp/tests/test_checksum.py +2 -1
- pyxcp/tests/test_daq.py +193 -0
- pyxcp/tests/test_frame_padding.py +6 -3
- pyxcp/tests/test_master.py +42 -31
- pyxcp/tests/test_transport.py +12 -12
- pyxcp/tests/test_utils.py +2 -5
- pyxcp/timing.py +0 -2
- pyxcp/transport/__init__.py +9 -9
- pyxcp/transport/base.py +149 -127
- pyxcp/transport/base_transport.hpp +0 -0
- pyxcp/transport/can.py +194 -167
- pyxcp/transport/eth.py +80 -82
- pyxcp/transport/sxi.py +106 -60
- pyxcp/transport/transport_wrapper.cpp +0 -0
- pyxcp/transport/usb_transport.py +65 -83
- pyxcp/types.py +69 -20
- pyxcp/utils.py +47 -16
- pyxcp/vector/map.py +1 -3
- {pyxcp-0.21.9.dist-info → pyxcp-0.22.23.dist-info}/METADATA +28 -23
- pyxcp-0.22.23.dist-info/RECORD +137 -0
- {pyxcp-0.21.9.dist-info → pyxcp-0.22.23.dist-info}/WHEEL +1 -1
- {pyxcp-0.21.9.dist-info → pyxcp-0.22.23.dist-info}/entry_points.txt +2 -0
- pyxcp/config.py +0 -57
- pyxcp/cxx/asynchiofactory.hpp +0 -24
- pyxcp/cxx/blocking_client.cpp +0 -44
- pyxcp/cxx/blocking_socket.cpp +0 -43
- pyxcp/cxx/blocking_socket.hpp +0 -558
- pyxcp/cxx/concurrent_queue.hpp +0 -60
- pyxcp/cxx/eth.hpp +0 -57
- pyxcp/cxx/exceptions.hpp +0 -30
- pyxcp/cxx/iasyncioservice.hpp +0 -31
- pyxcp/cxx/iresource.hpp +0 -17
- pyxcp/cxx/isocket.hpp +0 -22
- pyxcp/cxx/linux/epoll.cpp +0 -51
- pyxcp/cxx/linux/epoll.hpp +0 -87
- pyxcp/cxx/linux/lit_tester.cpp +0 -19
- pyxcp/cxx/linux/socket.hpp +0 -234
- pyxcp/cxx/linux/timeout.hpp +0 -81
- pyxcp/cxx/memoryblock.hpp +0 -42
- pyxcp/cxx/pool.hpp +0 -81
- pyxcp/cxx/poolmgr.cpp +0 -6
- pyxcp/cxx/poolmgr.hpp +0 -31
- pyxcp/cxx/test_queue.cpp +0 -69
- pyxcp/cxx/timestamp.hpp +0 -84
- pyxcp/cxx/utils.cpp +0 -38
- pyxcp/cxx/utils.hpp +0 -29
- pyxcp/cxx/win/iocp.cpp +0 -242
- pyxcp/cxx/win/iocp.hpp +0 -42
- pyxcp/cxx/win/perhandledata.hpp +0 -24
- pyxcp/cxx/win/periodata.hpp +0 -97
- pyxcp/cxx/win/socket.hpp +0 -185
- pyxcp/cxx/win/timeout.hpp +0 -83
- pyxcp/examples/conf_can.json +0 -20
- pyxcp/examples/conf_eth.json +0 -8
- pyxcp/logger.py +0 -67
- pyxcp/tests/test_config.py +0 -62
- pyxcp/transport/candriver/__init__.py +0 -2
- pyxcp/transport/candriver/pc_canalystii.py +0 -27
- pyxcp/transport/candriver/pc_etas.py +0 -25
- pyxcp/transport/candriver/pc_gsusb.py +0 -23
- pyxcp/transport/candriver/pc_iscan.py +0 -23
- pyxcp/transport/candriver/pc_ixxat.py +0 -27
- pyxcp/transport/candriver/pc_kvaser.py +0 -39
- pyxcp/transport/candriver/pc_neovi.py +0 -31
- pyxcp/transport/candriver/pc_nican.py +0 -23
- pyxcp/transport/candriver/pc_nixnet.py +0 -23
- pyxcp/transport/candriver/pc_pcan.py +0 -25
- pyxcp/transport/candriver/pc_seeed.py +0 -28
- pyxcp/transport/candriver/pc_serial.py +0 -27
- pyxcp/transport/candriver/pc_slcan.py +0 -29
- pyxcp/transport/candriver/pc_socketcan.py +0 -23
- pyxcp/transport/candriver/pc_systec.py +0 -29
- pyxcp/transport/candriver/pc_usb2can.py +0 -30
- pyxcp/transport/candriver/pc_vector.py +0 -34
- pyxcp/transport/candriver/python_can.py +0 -101
- pyxcp/transport/cxx_ext/CMakeLists.txt +0 -51
- pyxcp/transport/cxx_ext/setup.py +0 -49
- pyxcp/transport/cxx_ext/tests/test_basic_socket.cpp +0 -39
- pyxcp/transport/cxx_ext/tests/test_pool.cpp +0 -39
- pyxcp/transport/cxx_ext/tests/test_timestamp.cpp +0 -27
- pyxcp-0.21.9.dist-info/RECORD +0 -147
- rekorder.cp311-win_amd64.pyd +0 -0
- {pyxcp-0.21.9.dist-info/licenses → pyxcp-0.22.23.dist-info}/LICENSE +0 -0
pyxcp/cxx/poolmgr.hpp
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#if !defined(__POOLMGR_H)
|
|
2
|
-
#define __POOLMGR_H
|
|
3
|
-
|
|
4
|
-
#include "pool.hpp"
|
|
5
|
-
#include "periodata.hpp"
|
|
6
|
-
|
|
7
|
-
/*
|
|
8
|
-
*
|
|
9
|
-
* PoolManager holds various resource pools.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
class PoolManager {
|
|
15
|
-
public:
|
|
16
|
-
using IodPool_t = Pool<PerIoData, 64>;
|
|
17
|
-
|
|
18
|
-
PoolManager() = default;
|
|
19
|
-
~PoolManager() = default;
|
|
20
|
-
|
|
21
|
-
IodPool_t& get_iod() const {
|
|
22
|
-
return m_iod_pool;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
private:
|
|
26
|
-
|
|
27
|
-
static IodPool_t m_iod_pool;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
#endif // __POOLMGR_H
|
pyxcp/cxx/test_queue.cpp
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#include <cstdio>
|
|
3
|
-
|
|
4
|
-
#include <thread>
|
|
5
|
-
|
|
6
|
-
#include <pybind11/pybind11.h>
|
|
7
|
-
#include <pybind11/functional.h>
|
|
8
|
-
#include <pybind11/stl.h>
|
|
9
|
-
|
|
10
|
-
#include "concurrent_queue.hpp"
|
|
11
|
-
|
|
12
|
-
namespace py = pybind11;
|
|
13
|
-
|
|
14
|
-
auto queue = ConcurrentQueue<int> {};
|
|
15
|
-
|
|
16
|
-
using tuple_t = std::tuple<uint16_t, uint16_t, double, py::bytes>;
|
|
17
|
-
|
|
18
|
-
auto frame_queue = ConcurrentQueue<tuple_t> {};
|
|
19
|
-
|
|
20
|
-
void worker(int num)
|
|
21
|
-
{
|
|
22
|
-
printf("Entering #%u\n", num);
|
|
23
|
-
for (int i = 0; i < 10; ++i) {
|
|
24
|
-
queue.enqueue(num + i);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
int main(int ac, char const * av[])
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
auto value = 0;
|
|
33
|
-
auto frame = std::make_tuple(20, 1, 1.0045, "hello world!!!");
|
|
34
|
-
uint16_t length, counter;
|
|
35
|
-
double timestamp;
|
|
36
|
-
py::bytes payload {};
|
|
37
|
-
|
|
38
|
-
frame_queue.enqueue(frame);
|
|
39
|
-
|
|
40
|
-
std::thread t0(worker, 10);
|
|
41
|
-
std::thread t1(worker, 20);
|
|
42
|
-
std::thread t2(worker, 30);
|
|
43
|
-
std::thread t3(worker, 40);
|
|
44
|
-
std::thread t4(worker, 50);
|
|
45
|
-
|
|
46
|
-
for (auto i = 0; i < 100; ++i) {
|
|
47
|
-
if (queue.dequeue(value, 1000)) {
|
|
48
|
-
printf("%02u\n", value);
|
|
49
|
-
} else {
|
|
50
|
-
printf("TIME-OUT!!!\n");
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
t4.join();
|
|
56
|
-
t3.join();
|
|
57
|
-
t2.join();
|
|
58
|
-
t1.join();
|
|
59
|
-
t0.join();
|
|
60
|
-
|
|
61
|
-
tuple_t flonz;
|
|
62
|
-
frame_queue.dequeue(flonz);
|
|
63
|
-
//printf("%u %u %g\n", std::get<0>(flonz), std::get<1>(flonz), std::get<2>(flonz));
|
|
64
|
-
|
|
65
|
-
std::tie(length, counter, timestamp, payload) = flonz;
|
|
66
|
-
printf("%u %u %g\n", length, counter, timestamp);
|
|
67
|
-
|
|
68
|
-
return 0;
|
|
69
|
-
}
|
pyxcp/cxx/timestamp.hpp
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
#if !defined(__TIMESTAMP_HPP)
|
|
2
|
-
#define __TIMESTAMP_HPP
|
|
3
|
-
|
|
4
|
-
#include <cstdint>
|
|
5
|
-
|
|
6
|
-
#if defined(_WIN32)
|
|
7
|
-
#include <Windows.h>
|
|
8
|
-
#else
|
|
9
|
-
#include <time.h>
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
class Timestamp {
|
|
13
|
-
public:
|
|
14
|
-
|
|
15
|
-
#if defined(_WIN32)
|
|
16
|
-
Timestamp() {
|
|
17
|
-
LARGE_INTEGER tps;
|
|
18
|
-
|
|
19
|
-
::QueryPerformanceFrequency(&tps);
|
|
20
|
-
m_ticks_per_second = tps.QuadPart;
|
|
21
|
-
m_starting_time = static_cast<double>(get_raw_value());
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
double get() const {
|
|
25
|
-
return get_raw_value() - m_starting_time;
|
|
26
|
-
}
|
|
27
|
-
#else
|
|
28
|
-
Timestamp() {
|
|
29
|
-
struct timespec resolution = {0};
|
|
30
|
-
|
|
31
|
-
if (::clock_getres(CLOCK_MONOTONIC_RAW, &resolution) == -1) {
|
|
32
|
-
}
|
|
33
|
-
m_starting_time = get_raw_value();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
double get() const {
|
|
37
|
-
struct timespec dt = {0};
|
|
38
|
-
|
|
39
|
-
dt = diff(m_starting_time, get_raw_value());
|
|
40
|
-
return static_cast<double>(dt.tv_sec) + (static_cast<double>(dt.tv_nsec) / (1000.0 * 1000.0 * 1000.0));
|
|
41
|
-
}
|
|
42
|
-
#endif
|
|
43
|
-
|
|
44
|
-
private:
|
|
45
|
-
|
|
46
|
-
#if defined(_WIN32)
|
|
47
|
-
double get_raw_value() const {
|
|
48
|
-
LARGE_INTEGER now;
|
|
49
|
-
|
|
50
|
-
::QueryPerformanceCounter(&now);
|
|
51
|
-
|
|
52
|
-
return static_cast<double>(now.QuadPart) / static_cast<double>(m_ticks_per_second);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
double m_starting_time;
|
|
56
|
-
uint64_t m_ticks_per_second;
|
|
57
|
-
#else
|
|
58
|
-
struct timespec get_raw_value() const {
|
|
59
|
-
struct timespec now;
|
|
60
|
-
|
|
61
|
-
if (::clock_gettime(CLOCK_MONOTONIC_RAW, &now) == -1) {
|
|
62
|
-
}
|
|
63
|
-
return now;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
struct timespec diff(const struct timespec& start, const struct timespec& end) const {
|
|
67
|
-
struct timespec temp;
|
|
68
|
-
|
|
69
|
-
if ((end.tv_nsec-start.tv_nsec) < 0) {
|
|
70
|
-
temp.tv_sec = end.tv_sec-start.tv_sec - 1;
|
|
71
|
-
temp.tv_nsec = 1000000000L + end.tv_nsec - start.tv_nsec;
|
|
72
|
-
} else {
|
|
73
|
-
temp.tv_sec = end.tv_sec-start.tv_sec;
|
|
74
|
-
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
|
75
|
-
}
|
|
76
|
-
return temp;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
struct timespec m_starting_time;
|
|
80
|
-
|
|
81
|
-
#endif
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
#endif // __TIMESTAMP_HPP
|
pyxcp/cxx/utils.cpp
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#include <cstdio>
|
|
3
|
-
|
|
4
|
-
#include "utils.hpp"
|
|
5
|
-
|
|
6
|
-
#if defined(_WIN32)
|
|
7
|
-
#include <Windows.h>
|
|
8
|
-
#else
|
|
9
|
-
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
void SocketErrorExit(const char * method)
|
|
13
|
-
{
|
|
14
|
-
fprintf(stderr, "%s failed with: %d\n", method, GET_LAST_SOCKET_ERROR());
|
|
15
|
-
exit(1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
void OsErrorExit(const char * method)
|
|
19
|
-
{
|
|
20
|
-
fprintf(stderr, "%s failed with: %d\n", method, GET_LAST_ERROR());
|
|
21
|
-
exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
#if !defined(_WIN32)
|
|
25
|
-
/*
|
|
26
|
-
*
|
|
27
|
-
* Window-ish Sleep function for Linux.
|
|
28
|
-
*
|
|
29
|
-
*/
|
|
30
|
-
void Sleep(unsigned ms)
|
|
31
|
-
{
|
|
32
|
-
struct timespec value = {0}, rem = {0};
|
|
33
|
-
|
|
34
|
-
value.tv_sec = ms / 1000;
|
|
35
|
-
value.tv_nsec = (ms % 1000) * 1000 * 1000;
|
|
36
|
-
nanosleep(&value, &rem);
|
|
37
|
-
}
|
|
38
|
-
#endif
|
pyxcp/cxx/utils.hpp
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#if !defined(__UTILS_HPP)
|
|
2
|
-
#define __UTILS_HPP
|
|
3
|
-
|
|
4
|
-
#if defined(_WIN32)
|
|
5
|
-
#define ZeroOut(p, s) ::SecureZeroMemory((p), (s))
|
|
6
|
-
#define GET_LAST_SOCKET_ERROR() WSAGetLastError()
|
|
7
|
-
#define GET_LAST_ERROR() GetLastError()
|
|
8
|
-
#else
|
|
9
|
-
#include <stdlib.h>
|
|
10
|
-
#include <errno.h>
|
|
11
|
-
#include <time.h>
|
|
12
|
-
|
|
13
|
-
#define ZeroOut(p, s) ::memset((p), 0, (s))
|
|
14
|
-
#define CopyMemory(d, s, l) ::memcpy((d), (s), (l))
|
|
15
|
-
#define GET_LAST_SOCKET_ERROR() errno
|
|
16
|
-
#define GET_LAST_ERROR() errno
|
|
17
|
-
void Sleep(unsigned ms);
|
|
18
|
-
#endif
|
|
19
|
-
|
|
20
|
-
#if defined(NDEBUG)
|
|
21
|
-
#define DBG_PRINT(...)
|
|
22
|
-
#else
|
|
23
|
-
#define DBG_PRINT(...) printf(VA_ARGS)
|
|
24
|
-
#endif
|
|
25
|
-
|
|
26
|
-
void SocketErrorExit(const char * method);
|
|
27
|
-
void OsErrorExit(const char * method);
|
|
28
|
-
|
|
29
|
-
#endif // __UTILS_HPP
|
pyxcp/cxx/win/iocp.cpp
DELETED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#include "iocp.hpp"
|
|
3
|
-
#include "socket.hpp"
|
|
4
|
-
#include "exceptions.hpp"
|
|
5
|
-
#include "timeout.hpp"
|
|
6
|
-
|
|
7
|
-
#include <iostream>
|
|
8
|
-
#include <cstdio>
|
|
9
|
-
#include <cstddef>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
static DWORD WINAPI WorkerThread(LPVOID lpParameter);
|
|
20
|
-
|
|
21
|
-
IOCP::IOCP(size_t numProcessors, size_t multiplier)
|
|
22
|
-
{
|
|
23
|
-
m_numWorkerThreads = numProcessors * multiplier;
|
|
24
|
-
m_port.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, static_cast<ULONG_PTR>(0), m_numWorkerThreads);
|
|
25
|
-
if (m_port.handle == nullptr) {
|
|
26
|
-
OsErrorExit("IOCP::IOCP()");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
m_threads.reserve(m_numWorkerThreads);
|
|
30
|
-
|
|
31
|
-
HANDLE hThread;
|
|
32
|
-
|
|
33
|
-
for (DWORD idx = 0; idx < m_numWorkerThreads; ++idx) {
|
|
34
|
-
hThread = ::CreateThread(nullptr, 0, WorkerThread, reinterpret_cast<LPVOID>(this), 0, nullptr);
|
|
35
|
-
::SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
|
36
|
-
m_threads.push_back(hThread);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
IOCP::~IOCP()
|
|
41
|
-
{
|
|
42
|
-
DWORD numThreads = static_cast<DWORD>(m_threads.size());
|
|
43
|
-
std::ldiv_t divres = std::ldiv(numThreads, MAXIMUM_WAIT_OBJECTS);
|
|
44
|
-
DWORD rounds = static_cast<DWORD>(divres.quot);
|
|
45
|
-
DWORD remaining = static_cast<DWORD>(divres.rem);
|
|
46
|
-
HANDLE * thrArray = nullptr;
|
|
47
|
-
DWORD offset = 0;
|
|
48
|
-
DWORD idx = 0;
|
|
49
|
-
|
|
50
|
-
postQuitMessage();
|
|
51
|
-
|
|
52
|
-
thrArray = new HANDLE[MAXIMUM_WAIT_OBJECTS];
|
|
53
|
-
for (DWORD r = 0; r < rounds; ++r) {
|
|
54
|
-
for (idx = 0; idx < MAXIMUM_WAIT_OBJECTS; ++idx) {
|
|
55
|
-
thrArray[idx] = m_threads.at(idx + offset);
|
|
56
|
-
}
|
|
57
|
-
::WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, thrArray, TRUE, INFINITE);
|
|
58
|
-
for (idx = 0; idx < MAXIMUM_WAIT_OBJECTS; ++idx) {
|
|
59
|
-
::CloseHandle(thrArray[idx]);
|
|
60
|
-
}
|
|
61
|
-
offset += MAXIMUM_WAIT_OBJECTS;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (remaining > 0) {
|
|
65
|
-
for (idx = 0; idx < remaining; ++idx) {
|
|
66
|
-
thrArray[idx] = m_threads.at(idx + offset);
|
|
67
|
-
}
|
|
68
|
-
::WaitForMultipleObjects(remaining, thrArray, TRUE, INFINITE);
|
|
69
|
-
for (idx = 0; idx < remaining; ++idx) {
|
|
70
|
-
::CloseHandle(thrArray[idx]);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
delete[] thrArray;
|
|
74
|
-
::CloseHandle(m_port.handle);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
void IOCP::registerHandle(const PerHandleData& object)
|
|
78
|
-
{
|
|
79
|
-
HANDLE handle;
|
|
80
|
-
bool ok;
|
|
81
|
-
|
|
82
|
-
handle = ::CreateIoCompletionPort(object.m_handle, m_port.handle, reinterpret_cast<ULONG_PTR>(&object), 0);
|
|
83
|
-
ok = (handle == m_port.handle);
|
|
84
|
-
if ((handle == nullptr) || (!ok)) {
|
|
85
|
-
OsErrorExit("IOCP::registerHandle()");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
void IOCP::registerSocket(Socket& socket)
|
|
91
|
-
{
|
|
92
|
-
auto handleData = PerHandleData(HandleType::HANDLE_SOCKET, socket.getHandle());
|
|
93
|
-
|
|
94
|
-
socket.setIOCP(this);
|
|
95
|
-
registerHandle(handleData);
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
void IOCP::postUserMessage(MessageCode messageCode, void * data) const
|
|
100
|
-
{
|
|
101
|
-
if (!::PostQueuedCompletionStatus(m_port.handle, 0, static_cast<ULONG_PTR>(messageCode), (OVERLAPPED*)data)) {
|
|
102
|
-
OsErrorExit("IOCP::postUserMessage()");
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
void IOCP::postQuitMessage() const
|
|
107
|
-
{
|
|
108
|
-
postUserMessage(MessageCode::QUIT, nullptr);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
HANDLE IOCP::getHandle() const
|
|
112
|
-
{
|
|
113
|
-
return m_port.handle;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
static DWORD WINAPI WorkerThread(LPVOID lpParameter)
|
|
117
|
-
{
|
|
118
|
-
IOCP const * const iocp = reinterpret_cast<IOCP const * const>(lpParameter);
|
|
119
|
-
DWORD bytesTransfered = 0;
|
|
120
|
-
ULONG_PTR completionKey;
|
|
121
|
-
PerIoData * iod = nullptr;
|
|
122
|
-
PerHandleData * phd = nullptr;
|
|
123
|
-
OVERLAPPED * olap = nullptr;
|
|
124
|
-
bool exitLoop = false;
|
|
125
|
-
MessageCode messageCode;
|
|
126
|
-
DWORD error;
|
|
127
|
-
|
|
128
|
-
printf("Entering worker thread %d.\n", ::GetCurrentThreadId());
|
|
129
|
-
while (!exitLoop) {
|
|
130
|
-
if (::GetQueuedCompletionStatus(iocp->getHandle(), &bytesTransfered, &completionKey, (LPOVERLAPPED*)&olap, INFINITE)) {
|
|
131
|
-
if (bytesTransfered == 0) {
|
|
132
|
-
messageCode = static_cast<MessageCode>(completionKey);
|
|
133
|
-
if (messageCode == MessageCode::TIMEOUT) {
|
|
134
|
-
// TODO: Timeout handling.
|
|
135
|
-
} else if (messageCode == MessageCode::QUIT) {
|
|
136
|
-
iocp->postQuitMessage(); // "Broadcast"
|
|
137
|
-
exitLoop = true;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
} else {
|
|
141
|
-
phd = reinterpret_cast<PerHandleData *>(completionKey);
|
|
142
|
-
iod = reinterpret_cast<PerIoData* >(olap);
|
|
143
|
-
printf("\tOPCODE: %d bytes: %d\n", iod->get_opcode(), bytesTransfered);
|
|
144
|
-
switch (iod->get_opcode()) {
|
|
145
|
-
case IoType::IO_WRITE:
|
|
146
|
-
iod->decr_bytes_to_xfer(bytesTransfered);
|
|
147
|
-
// phd->m_socket->triggerRead(1024);
|
|
148
|
-
if (iod->xfer_finished()) {
|
|
149
|
-
delete iod;
|
|
150
|
-
} else {
|
|
151
|
-
//iod->m_wsabuf.buf = iod->m_wsabuf.buf + (iod->get_bytes_to_xfer() - iod->m_bytesRemaining);
|
|
152
|
-
//iod->m_wsabuf.len = iod->m_bytesRemaining;
|
|
153
|
-
iod->reset();
|
|
154
|
-
}
|
|
155
|
-
break;
|
|
156
|
-
case IoType::IO_READ:
|
|
157
|
-
printf("IO_READ() numBytes: %d\n", bytesTransfered);
|
|
158
|
-
break;
|
|
159
|
-
case IoType::IO_ACCEPT:
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
} else {
|
|
164
|
-
error = ::GetLastError();
|
|
165
|
-
if (olap == nullptr) {
|
|
166
|
-
|
|
167
|
-
} else {
|
|
168
|
-
// Failed I/O operation.
|
|
169
|
-
// The function stores information in the variables pointed to by lpNumberOfBytes, lpCompletionKey.
|
|
170
|
-
}
|
|
171
|
-
//Win_ErrorMsg("IOWorkerThread::GetQueuedCompletionStatus()", error);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
printf("Exiting worker thread %d\n", ::GetCurrentThreadId());
|
|
175
|
-
::ExitThread(0);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
void CALLBACK Timeout_CB(void * lpParam, unsigned char TimerOrWaitFired)
|
|
179
|
-
{
|
|
180
|
-
IOCP const * const iocp = reinterpret_cast<IOCP const * const>(lpParam);
|
|
181
|
-
|
|
182
|
-
//printf("TIMEOUT\n");
|
|
183
|
-
iocp->postUserMessage(MessageCode::TIMEOUT);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
#if 0
|
|
188
|
-
void Socket::triggerRead(unsigned int len)
|
|
189
|
-
{
|
|
190
|
-
DWORD numReceived = (DWORD)0;
|
|
191
|
-
DWORD flags = (DWORD)0;
|
|
192
|
-
DWORD err = 0;
|
|
193
|
-
int addrLen;
|
|
194
|
-
static char buf[1024];
|
|
195
|
-
|
|
196
|
-
PerIoData * iod = new PerIoData(128);
|
|
197
|
-
|
|
198
|
-
iod->m_wsabuf.buf = buf;
|
|
199
|
-
iod->m_wsabuf.len = len;
|
|
200
|
-
iod->m_opcode = IoType::IO_READ;
|
|
201
|
-
iod->m_bytesRemaining = iod->m_bytesToXfer = len;
|
|
202
|
-
iod->reset();
|
|
203
|
-
|
|
204
|
-
if (m_socktype == SOCK_STREAM) {
|
|
205
|
-
if (WSARecv(m_socket,
|
|
206
|
-
&iod->m_wsabuf,
|
|
207
|
-
1,
|
|
208
|
-
&numReceived,
|
|
209
|
-
&flags,
|
|
210
|
-
(LPWSAOVERLAPPED)&iod->m_overlapped,
|
|
211
|
-
(LPWSAOVERLAPPED_COMPLETION_ROUTINE)nullptr) == SOCKET_ERROR) {
|
|
212
|
-
err = WSAGetLastError();
|
|
213
|
-
if (err != WSA_IO_PENDING) {
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
} else if (m_socktype == SOCK_DGRAM) {
|
|
218
|
-
addrLen = sizeof(SOCKADDR_STORAGE);
|
|
219
|
-
if (WSARecvFrom(m_socket,
|
|
220
|
-
&iod->m_wsabuf,
|
|
221
|
-
1,
|
|
222
|
-
&numReceived,
|
|
223
|
-
&flags,
|
|
224
|
-
(LPSOCKADDR)&numReceived,
|
|
225
|
-
&addrLen,
|
|
226
|
-
(LPWSAOVERLAPPED)&iod->m_overlapped,
|
|
227
|
-
(LPWSAOVERLAPPED_COMPLETION_ROUTINE)nullptr)) {
|
|
228
|
-
err = WSAGetLastError();
|
|
229
|
-
if (err != WSA_IO_PENDING) {
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
typedef std::function<void(DWORD transferred)> CompleteHandler_t;
|
|
237
|
-
|
|
238
|
-
class AsyncIoServiceFactory {
|
|
239
|
-
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
#endif
|
pyxcp/cxx/win/iocp.hpp
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
#if !defined(__IOCP_HPP)
|
|
2
|
-
#define __IOCP_HPP
|
|
3
|
-
|
|
4
|
-
#include "iasyncioservice.hpp"
|
|
5
|
-
#include "socket.hpp"
|
|
6
|
-
#include "perhandledata.hpp"
|
|
7
|
-
#include "periodata.hpp"
|
|
8
|
-
#include "poolmgr.hpp"
|
|
9
|
-
#include <cassert>
|
|
10
|
-
#include <cstdint>
|
|
11
|
-
#include <vector>
|
|
12
|
-
|
|
13
|
-
#if !defined(__GNUC__)
|
|
14
|
-
#pragma comment(lib,"ws2_32.lib") // MSVC only.
|
|
15
|
-
#endif
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
struct PerPortData {
|
|
19
|
-
HANDLE handle;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class IOCP : public IAsyncIoService {
|
|
24
|
-
public:
|
|
25
|
-
IOCP(size_t numProcessors = 1, size_t multiplier = 1);
|
|
26
|
-
~IOCP();
|
|
27
|
-
void registerSocket(Socket& socket);
|
|
28
|
-
void postUserMessage(MessageCode messageCode, void * data = nullptr) const;
|
|
29
|
-
void postQuitMessage() const;
|
|
30
|
-
HANDLE getHandle() const;
|
|
31
|
-
|
|
32
|
-
protected:
|
|
33
|
-
void registerHandle(const PerHandleData& object);
|
|
34
|
-
|
|
35
|
-
private:
|
|
36
|
-
PerPortData m_port;
|
|
37
|
-
DWORD m_numWorkerThreads;
|
|
38
|
-
std::vector<HANDLE> m_threads;
|
|
39
|
-
PoolManager m_pool_mgr;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
#endif // __IOCP_HPP
|
pyxcp/cxx/win/perhandledata.hpp
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#if !defined(__PERHANDLEDATA_HPP)
|
|
2
|
-
#define __PERHANDLEDATA_HPP
|
|
3
|
-
|
|
4
|
-
#include <Windows.h>
|
|
5
|
-
|
|
6
|
-
enum class HandleType {
|
|
7
|
-
HANDLE_SOCKET,
|
|
8
|
-
HANDLE_FILE,
|
|
9
|
-
HANDLE_NAMED_PIPE,
|
|
10
|
-
HANDLE_USER,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
struct PerHandleData {
|
|
15
|
-
HandleType m_handleType;
|
|
16
|
-
HANDLE m_handle;
|
|
17
|
-
DWORD m_seqNoSend;
|
|
18
|
-
DWORD m_seqNoRecv;
|
|
19
|
-
|
|
20
|
-
PerHandleData(HandleType handleType, const HANDLE& handle) : m_handleType(handleType), m_handle(handle), m_seqNoSend(0), m_seqNoRecv(0) {}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
#endif // __PERHANDLEDATA_HPP
|
pyxcp/cxx/win/periodata.hpp
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#if !defined(__PERIODATA_HPP)
|
|
2
|
-
#define __PERIODATA_HPP
|
|
3
|
-
|
|
4
|
-
#include <array>
|
|
5
|
-
#include <cassert>
|
|
6
|
-
#include "utils.hpp"
|
|
7
|
-
#include <WinSock2.h>
|
|
8
|
-
|
|
9
|
-
enum class IoType {
|
|
10
|
-
IO_ACCEPT,
|
|
11
|
-
IO_CONNECT,
|
|
12
|
-
IO_READ,
|
|
13
|
-
IO_WRITE
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
class PerIoData {
|
|
17
|
-
|
|
18
|
-
public:
|
|
19
|
-
|
|
20
|
-
explicit PerIoData(size_t bufferSize = 128) {
|
|
21
|
-
m_xferBuffer = nullptr;
|
|
22
|
-
m_xferBuffer = new char[bufferSize];
|
|
23
|
-
m_wsabuf.buf = m_xferBuffer;
|
|
24
|
-
|
|
25
|
-
m_wsabuf.len = bufferSize;
|
|
26
|
-
m_bytesRemaining = 0;
|
|
27
|
-
m_bytes_to_xfer = 0;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
~PerIoData() {
|
|
31
|
-
if (m_xferBuffer) {
|
|
32
|
-
delete[] m_xferBuffer;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
void setup_write_request() {
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
void set_opcode(IoType opcode) {
|
|
41
|
-
m_opcode = opcode;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
template <typename T, size_t N> void set_buffer(std::array<T, N>& arr) {
|
|
45
|
-
|
|
46
|
-
m_wsabuf.buf = arr.data();
|
|
47
|
-
m_wsabuf.len = arr.size();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
WSABUF * get_buffer() {
|
|
51
|
-
return &m_wsabuf;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
IoType get_opcode() const {
|
|
55
|
-
return m_opcode;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
void set_transfer_length(size_t length) {
|
|
59
|
-
m_bytesRemaining = m_bytes_to_xfer = length;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
size_t get_bytes_to_xfer() const {
|
|
63
|
-
return m_bytes_to_xfer;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
void decr_bytes_to_xfer(size_t amount) {
|
|
67
|
-
printf("remaining: %d amount: %d\n",m_bytesRemaining, amount);
|
|
68
|
-
assert((static_cast<int64_t>(m_bytesRemaining) - static_cast<int64_t>(amount)) >= 0);
|
|
69
|
-
|
|
70
|
-
m_bytesRemaining -= amount;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
bool xfer_finished() const {
|
|
74
|
-
return m_bytesRemaining == 0;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
OVERLAPPED * get_overlapped() {
|
|
78
|
-
return &m_overlapped;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
void reset() {
|
|
82
|
-
ZeroOut(&m_overlapped, sizeof(OVERLAPPED));
|
|
83
|
-
m_wsabuf.len = 0;
|
|
84
|
-
m_bytesRemaining = 0;
|
|
85
|
-
m_bytes_to_xfer = 0;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private:
|
|
89
|
-
OVERLAPPED m_overlapped;
|
|
90
|
-
IoType m_opcode;
|
|
91
|
-
WSABUF m_wsabuf;
|
|
92
|
-
char * m_xferBuffer;
|
|
93
|
-
size_t m_bytes_to_xfer;
|
|
94
|
-
size_t m_bytesRemaining;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
#endif // __PERIODATA_HPP
|