The Pedigree Project 0.1
util.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/Process.h"
21#include "pedigree/kernel/processor/Processor.h"
22
23#include "modules/subsys/posix/FileDescriptor.h"
24#include "modules/subsys/posix/PosixSubsystem.h"
25
26#if UTILITY_LINUX
27#include <mutex>
28#include <vector>
29
30std::vector<SharedPointer<FileDescriptor>> g_Descriptors;
31std::mutex g_DescriptorsLock;
32
33bool acquireDescriptor(int fd, DescriptorLease& descriptor) {
34 descriptor.reset();
35 std::lock_guard<std::mutex> guard(g_DescriptorsLock);
36 if (fd < 0 || static_cast<size_t>(fd) >= g_Descriptors.size()) {
37 return false;
38 }
39
40 descriptor.retain(g_Descriptors[fd]);
41 return static_cast<bool>(descriptor);
42}
43
44void addDescriptor(int fd, FileDescriptor* f) {
45 if (fd < 0) {
46 delete f;
47 return;
48 }
49
50 SharedPointer<FileDescriptor> replacement(f);
52 {
53 std::lock_guard<std::mutex> guard(g_DescriptorsLock);
54 if (static_cast<size_t>(fd) >= g_Descriptors.size()) {
55 g_Descriptors.resize(fd + 1);
56 }
57
58 retiring = pedigree_std::move(g_Descriptors[fd]);
59 g_Descriptors[fd] = pedigree_std::move(replacement);
60 }
61 if (retiring) {
62 retiring->unpublish();
63 }
64 retiring.reset();
65}
66
67bool removeDescriptor(int fd, const DescriptorLease& descriptor) {
69 {
70 std::lock_guard<std::mutex> guard(g_DescriptorsLock);
71 if (fd < 0 || static_cast<size_t>(fd) >= g_Descriptors.size() ||
72 g_Descriptors[fd] != descriptor.m_Descriptor) {
73 return false;
74 }
75
76 retiring = pedigree_std::move(g_Descriptors[fd]);
77 }
78
79 if (retiring) {
80 retiring->unpublish();
81 }
82 retiring.reset();
83 return true;
84}
85
86size_t getAvailableDescriptor() {
87 std::lock_guard<std::mutex> guard(g_DescriptorsLock);
88 const size_t descriptor = g_Descriptors.size();
89 g_Descriptors.resize(descriptor + 1);
90 return descriptor;
91}
92
93size_t installDescriptor(FileDescriptor* descriptor, DescriptorLease& lease) {
94 SharedPointer<FileDescriptor> published(descriptor);
95 std::lock_guard<std::mutex> guard(g_DescriptorsLock);
96 const size_t fd = g_Descriptors.size();
97 descriptor->fd = fd;
98 g_Descriptors.push_back(published);
99 lease.retain(published);
100 return fd;
101}
102#else
104PosixSubsystem* getSubsystem() {
105 Process* pProcess = Processor::information().getCurrentThread()->getParent();
106 PosixSubsystem* pSubsystem = static_cast<PosixSubsystem*>(pProcess->getSubsystem());
107 if (!pSubsystem) {
108 ERROR("No subsystem for this process!");
109 return nullptr;
110 }
111
112 return pSubsystem;
113}
114
115bool acquireDescriptor(int fd, DescriptorLease& descriptor) {
116 PosixSubsystem* pSubsystem = getSubsystem();
117 if (!pSubsystem) {
118 descriptor.reset();
119 return false;
120 }
121 return pSubsystem->acquireFileDescriptor(fd, descriptor);
122}
123
124void addDescriptor(int fd, FileDescriptor* f) {
125 PosixSubsystem* pSubsystem = getSubsystem();
126 pSubsystem->addFileDescriptor(fd, f);
127}
128
129bool removeDescriptor(int fd, const DescriptorLease& descriptor) {
130 PosixSubsystem* pSubsystem = getSubsystem();
131 return pSubsystem && pSubsystem->closeFileDescriptor(fd, descriptor);
132}
133
134size_t getAvailableDescriptor() {
135 PosixSubsystem* pSubsystem = getSubsystem();
136 return pSubsystem->getFd();
137}
138
139size_t installDescriptor(FileDescriptor* descriptor, DescriptorLease& lease) {
140 return getSubsystem()->installFileDescriptor(descriptor, lease);
141}
142#endif
size_t fd
Descriptor number.
bool acquireFileDescriptor(size_t fd, DescriptorLease &descriptor)
bool closeFileDescriptor(size_t fd, const DescriptorLease &descriptor)
size_t getFd(size_t minimum=0)
size_t installFileDescriptor(FileDescriptor *descriptor, DescriptorLease &lease, size_t minimum=0)
void addFileDescriptor(size_t fd, FileDescriptor *pFd)
Process * getParent()
Definition Process.h:620
static ProcessorInformation & information()