Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : #pragma once
3 : :
4 : : #include <hpactor/types/types.hpp>
5 : : #include <sys/socket.h>
6 : : #include <sys/uio.h>
7 : :
8 : : #include <functional>
9 : :
10 : : namespace hpactor {
11 : : namespace net {
12 : :
13 : : enum class OpType : uint32_t {
14 : : Send = 1,
15 : : Recv = 2,
16 : : Accept = 3,
17 : : Connect = 4,
18 : : TimerFired = 5,
19 : : RecvFrom = 6,
20 : : SendTo = 7,
21 : : };
22 : :
23 : : struct OpCompletion {
24 : : ActorId actor;
25 : : OpType type;
26 : : int fd;
27 : : int result;
28 : : uint64_t user_data = 0;
29 : : sockaddr_in src_addr = {};
30 : : socklen_t src_addr_len = 0;
31 : : };
32 : :
33 : : // Read handler callback type - called when fd is readable.
34 : : // The callback owns the read: it must ::read() from the fd directly.
35 : : using read_callback = std::function<void(int fd)>;
36 : :
37 : : // Write handler callback type - called when fd is writable.
38 : : // Used for non-blocking connect completion: callback checks SO_ERROR
39 : : // and transitions the connection to Connected on success.
40 : : using write_callback = std::function<void(int fd)>;
41 : :
42 : : // Encode actor, fd, and op_type into a single uint64_t for user_data field.
43 : : // Format: bits 0-31 = fd, bits 32-47 = actor_id, bits 48-55 = reserved,
44 : : // bits 56-63 = op_type
45 : 1 : inline uint64_t encode_user_data(int fd, ActorId actor, uint32_t op_type) {
46 : 2 : return (static_cast<uint64_t>(fd) & 0xFFFFFFFFULL) |
47 : 1 : ((actor.value() & 0xFFFFULL) << 32) |
48 : 1 : ((static_cast<uint64_t>(op_type) & 0xFFULL) << 56);
49 : : }
50 : :
51 : : // Decode user_data back into fd, actor, and op_type
52 : 1 : inline void decode_user_data(uint64_t user_data, int& fd, ActorId& actor,
53 : : uint32_t& op_type) {
54 : 1 : fd = static_cast<int>(user_data & 0xFFFFFFFFULL);
55 : 1 : actor = ActorId(static_cast<uint32_t>((user_data >> 32) & 0xFFFFULL));
56 : 1 : op_type = static_cast<uint32_t>((user_data >> 56) & 0xFFULL);
57 : 1 : }
58 : :
59 : : // Unpack an OpCompletion from a StreamBuffer previously packed by
60 : : // ActorSystem::enqueue_completion. Returns false if the payload size
61 : : // does not match sizeof(OpCompletion).
62 : : inline bool unpack_completion(const StreamBuffer& payload, OpCompletion& out) {
63 : : if (payload.size() != sizeof(OpCompletion)) return false;
64 : : std::memcpy(&out, payload.data(), sizeof(OpCompletion));
65 : : return true;
66 : : }
67 : :
68 : : } // namespace net
69 : : } // namespace hpactor
|