The Pedigree Project 0.1
NativeIpc.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/process/Ipc.h"
21#include "pedigree/kernel/process/Process.h"
22#include "pedigree/kernel/process/Thread.h"
23#include "pedigree/kernel/processor/Processor.h"
24#include "pedigree/kernel/utilities/Pair.h"
25#include "pedigree/kernel/utilities/String.h"
26#include "pedigree/kernel/utilities/Tree.h"
27#include "pedigree/native/ipc/Ipc.h"
28
29#include <native-ipc.h>
30
32
36
37static inline uint64_t getPid() {
38 return Processor::information().getCurrentThread()->getParent()->getId();
39}
40
41uintptr_t createStandardMessage(PedigreeIpc::IpcMessage* pMessage) {
42 PerProcessUserPointerPair p = makePair(getPid(), pMessage);
43
44 Ipc::IpcMessage* pKernelMessage = new Ipc::IpcMessage();
45 Ipc::IpcMessage* pCheck = __msg_lookup.lookup(p);
46 if (pCheck) {
47 FATAL(
48 "Inserting an already allocated IPC message "
49 "[createStandardMessage].");
50 }
51 __msg_lookup.insert(p, pKernelMessage);
52
53 return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
54}
55
56uintptr_t createSharedMessage(PedigreeIpc::IpcMessage* pMessage, size_t nBytes, uintptr_t handle) {
57 PerProcessUserPointerPair p = makePair(getPid(), pMessage);
58
59 Ipc::IpcMessage* pKernelMessage = new Ipc::IpcMessage(nBytes, handle);
60 __msg_lookup.insert(p, pKernelMessage);
61
62 return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
63}
64
65void* getIpcSharedRegion(PedigreeIpc::IpcMessage* pMessage) {
66 PerProcessUserPointerPair p = makePair(getPid(), pMessage);
67
68 Ipc::IpcMessage* pKernelMessage = __msg_lookup.lookup(p);
69 if (pKernelMessage)
70 return pKernelMessage->getHandle();
71
72 return 0;
73}
74
75void destroyMessage(PedigreeIpc::IpcMessage* pMessage) {
76 PerProcessUserPointerPair p = makePair(getPid(), pMessage);
77
78 Ipc::IpcMessage* pKernelMessage = __msg_lookup.lookup(p);
79 if (pKernelMessage) {
80 __msg_lookup.remove(p);
81 delete pKernelMessage;
82 }
83}
84
85bool sendIpc(PedigreeIpc::IpcEndpoint pEndpoint, PedigreeIpc::IpcMessage* pMessage, bool bAsync) {
86 PerProcessUserPointerPair p = makePair(getPid(), pMessage);
87
88 Ipc::IpcMessage* pKernelMessage = __msg_lookup.lookup(p);
89 if (pKernelMessage) {
90 return Ipc::send(reinterpret_cast<Ipc::IpcEndpoint*>(pEndpoint), pKernelMessage, bAsync);
91 }
92
93 return false;
94}
95
96void* recvIpcPhase1(PedigreeIpc::IpcEndpoint pEndpoint, bool bAsync) {
97 Ipc::IpcMessage* pMessage = 0;
98 bool ret = Ipc::recv(reinterpret_cast<Ipc::IpcEndpoint*>(pEndpoint), &pMessage, bAsync);
99 if (!ret)
100 return 0;
101
102 return reinterpret_cast<void*>(pMessage);
103}
104
105uintptr_t recvIpcPhase2(PedigreeIpc::IpcMessage* pUserMessage, void* pMessage) {
106 PerProcessUserPointerPair p = makePair(getPid(), pUserMessage);
107
108 Ipc::IpcMessage* pKernelMessage = reinterpret_cast<Ipc::IpcMessage*>(pMessage);
109 Ipc::IpcMessage* pCheck = __msg_lookup.lookup(p);
110 if (pCheck) {
111 FATAL("Inserting an already allocated IPC message [recvIpcPhase2].");
112 }
113 __msg_lookup.insert(p, pKernelMessage);
114
115 return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
116}
117
118void createEndpoint(const char* name) {
119 String temp(name);
120 Ipc::createEndpoint(temp);
121}
122
123void removeEndpoint(const char* name) {
124 String temp(name);
125 Ipc::removeEndpoint(temp);
126}
127
128PedigreeIpc::IpcEndpoint* getEndpoint(const char* name) {
129 String temp(name);
130 return reinterpret_cast<PedigreeIpc::IpcEndpoint*>(Ipc::getEndpoint(temp));
131}
Definition Pair.h:30
A standard IPC message that is less than 4 KB in size.
static ProcessorInformation & information()
A key/value dictionary.
Definition Tree.h:33