| 29 | }; |
| 30 | |
| 31 | class MessageEndpoint final : public KernelObject{ |
| 32 | private: |
| 33 | friend Pair<FancyRefPtr<MessageEndpoint>,FancyRefPtr<MessageEndpoint>> CreatePair(); |
| 34 | uint16_t maxMessageSize = 8; |
| 35 | uint16_t messageQueueLimit = 128; |
| 36 | lock_t queueLock = 0; |
| 37 | |
| 38 | Semaphore queueAvailablilitySemaphore = Semaphore(messageQueueLimit); |
| 39 | |
| 40 | RingBuffer<Message> queue; |
| 41 | |
| 42 | FancyRefPtr<MessageEndpoint> peer; |
| 43 | |
| 44 | List<KernelObjectWatcher*> waiting; |
| 45 | List<Pair<Semaphore*, Reponse>> waitingResponse; |
| 46 | |
| 47 | lock_t waitingLock = 0; |
| 48 | lock_t waitingResponseLock = 0; |
| 49 | public: |
| 50 | static const uint16_t maxMessageSizeLimit = UINT16_MAX; |
| 51 | |
| 52 | static Pair<FancyRefPtr<MessageEndpoint>,FancyRefPtr<MessageEndpoint>> CreatePair(uint16_t msgSize){ |
| 53 | FancyRefPtr<MessageEndpoint> endpoint1 = FancyRefPtr<MessageEndpoint>(new MessageEndpoint(msgSize)); |
| 54 | FancyRefPtr<MessageEndpoint> endpoint2 = FancyRefPtr<MessageEndpoint>(new MessageEndpoint(msgSize)); |
| 55 | |
| 56 | endpoint1->peer = endpoint2; |
| 57 | endpoint2->peer = endpoint1; |
| 58 | |
| 59 | return {endpoint1, endpoint2}; |
| 60 | } |
| 61 | |
| 62 | MessageEndpoint(uint16_t maxSize); |
| 63 | ~MessageEndpoint(); |
| 64 | |
| 65 | void Destroy(); |
| 66 | |
| 67 | ///////////////////////////// |
| 68 | /// \brief Read a message from the queue |
| 69 | /// |
| 70 | /// Check if there are any available messages for reading and attempts to read one off the queue. |
| 71 | /// |
| 72 | /// \param id Pointer to the ID to be populated |
| 73 | /// \param size Pointer to the message size to be populated |
| 74 | /// \param data Pointer to an unsigned integer representing either 8 bytes of data (size <= 8) or a pointer to a buffer of size length containing message data |
| 75 | /// |
| 76 | /// \return 0 on success, 1 on empty, negative error code on failure |
| 77 | ///////////////////////////// |
| 78 | int64_t Read(uint64_t* id, uint16_t* size, uint64_t* data); |
| 79 | |
| 80 | ///////////////////////////// |
| 81 | /// \brief Send a message and return the response |
| 82 | /// |
| 83 | /// Sends a message to the peer and blocks until it receives a reply or the timeout period is expired. |
| 84 | /// Useful for RPC |
| 85 | /// |
| 86 | /// \param id ID of the message to be sent |
| 87 | /// \param size Size of the message to be sent |
| 88 | /// \param data Either a pointer to data (size > 8) or 8 bytes of data to be sent (size <= 8) |