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/native/ipc/Ipc.h"
25 
26 #include "pedigree/kernel/utilities/Pair.h"
27 #include "pedigree/kernel/utilities/String.h"
28 #include "pedigree/kernel/utilities/Tree.h"
29 
30 #include <native-ipc.h>
31 
33 
37  __msg_lookup;
38 
39 static inline uint64_t getPid()
40 {
41  return Processor::information().getCurrentThread()->getParent()->getId();
42 }
43 
44 uintptr_t createStandardMessage(PedigreeIpc::IpcMessage *pMessage)
45 {
46  PerProcessUserPointerPair p = makePair(getPid(), pMessage);
47 
48  Ipc::IpcMessage *pKernelMessage = new Ipc::IpcMessage();
49  Ipc::IpcMessage *pCheck = __msg_lookup.lookup(p);
50  if (pCheck)
51  {
52  FATAL("Inserting an already allocated IPC message "
53  "[createStandardMessage].");
54  }
55  __msg_lookup.insert(p, pKernelMessage);
56 
57  return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
58 }
59 
60 uintptr_t createSharedMessage(
61  PedigreeIpc::IpcMessage *pMessage, size_t nBytes, uintptr_t handle)
62 {
63  PerProcessUserPointerPair p = makePair(getPid(), pMessage);
64 
65  Ipc::IpcMessage *pKernelMessage = new Ipc::IpcMessage(nBytes, handle);
66  __msg_lookup.insert(p, pKernelMessage);
67 
68  return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
69 }
70 
71 void *getIpcSharedRegion(PedigreeIpc::IpcMessage *pMessage)
72 {
73  PerProcessUserPointerPair p = makePair(getPid(), pMessage);
74 
75  Ipc::IpcMessage *pKernelMessage = __msg_lookup.lookup(p);
76  if (pKernelMessage)
77  return pKernelMessage->getHandle();
78 
79  return 0;
80 }
81 
82 void destroyMessage(PedigreeIpc::IpcMessage *pMessage)
83 {
84  PerProcessUserPointerPair p = makePair(getPid(), pMessage);
85 
86  Ipc::IpcMessage *pKernelMessage = __msg_lookup.lookup(p);
87  if (pKernelMessage)
88  {
89  __msg_lookup.remove(p);
90  delete pKernelMessage;
91  }
92 }
93 
94 bool sendIpc(
95  PedigreeIpc::IpcEndpoint *pEndpoint, PedigreeIpc::IpcMessage *pMessage,
96  bool bAsync)
97 {
98  PerProcessUserPointerPair p = makePair(getPid(), pMessage);
99 
100  Ipc::IpcMessage *pKernelMessage = __msg_lookup.lookup(p);
101  if (pKernelMessage)
102  {
103  return Ipc::send(
104  reinterpret_cast<Ipc::IpcEndpoint *>(pEndpoint), pKernelMessage,
105  bAsync);
106  }
107 
108  return false;
109 }
110 
111 void *recvIpcPhase1(PedigreeIpc::IpcEndpoint *pEndpoint, bool bAsync)
112 {
113  Ipc::IpcMessage *pMessage = 0;
114  bool ret = Ipc::recv(
115  reinterpret_cast<Ipc::IpcEndpoint *>(pEndpoint), &pMessage, bAsync);
116  if (!ret)
117  return 0;
118 
119  return reinterpret_cast<void *>(pMessage);
120 }
121 
122 uintptr_t recvIpcPhase2(PedigreeIpc::IpcMessage *pUserMessage, void *pMessage)
123 {
124  PerProcessUserPointerPair p = makePair(getPid(), pUserMessage);
125 
126  Ipc::IpcMessage *pKernelMessage =
127  reinterpret_cast<Ipc::IpcMessage *>(pMessage);
128  Ipc::IpcMessage *pCheck = __msg_lookup.lookup(p);
129  if (pCheck)
130  {
131  FATAL("Inserting an already allocated IPC message [recvIpcPhase2].");
132  }
133  __msg_lookup.insert(p, pKernelMessage);
134 
135  return reinterpret_cast<uintptr_t>(pKernelMessage->getBuffer());
136 }
137 
138 void createEndpoint(const char *name)
139 {
140  String temp(name);
141  Ipc::createEndpoint(temp);
142 }
143 
144 void removeEndpoint(const char *name)
145 {
146  String temp(name);
147  Ipc::removeEndpoint(temp);
148 }
149 
150 PedigreeIpc::IpcEndpoint *getEndpoint(const char *name)
151 {
152  String temp(name);
153  return reinterpret_cast<PedigreeIpc::IpcEndpoint *>(Ipc::getEndpoint(temp));
154 }
Definition: Pair.h:30
Definition: String.h:49
static ProcessorInformation & information()
Definition: Processor.cc:45
A standard IPC message that is less than 4 KB in size.
void insert(const K &key, const E &value)
Definition: Tree.h:173
A key/value dictionary.
Definition: Tree.h:33
void remove(const K &key)
Definition: Tree.h:242
#define FATAL(text)
Definition: Log.h:89
E lookup(const K &key) const
Definition: Tree.h:192