The Pedigree Project 0.1
ServiceManager.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/LockGuard.h"
21#include "pedigree/kernel/Service.h"
22#include "pedigree/kernel/ServiceManager.h"
23#include "pedigree/kernel/process/TerminationDeferral.h"
24#include "pedigree/kernel/processor/Processor.h"
25#include "pedigree/kernel/utilities/List.h"
26#include "pedigree/kernel/utilities/new"
27
28ServiceManager ServiceManager::m_Instance;
29
30ServiceManager::ServiceManager() : m_Lock(), m_Services() {}
31
32ServiceManager::~ServiceManager() {
34 {
36 for (auto* service : m_Services) {
37 service->operations.close();
38 services.pushBack(service);
39 }
40 m_Services.clear();
41 }
42 for (auto* service : services) {
43 service->operations.wait();
44 delete service;
45 }
46}
47
50 RadixTree<InternalService*>::LookupType result = m_Services.lookup(serviceName);
51 if (result.hasValue()) {
52 return result.value()->pFeatures;
53 } else {
54 return 0;
55 }
56}
57
58void ServiceManager::addService(const String& serviceName, Service* s, ServiceFeatures* feats) {
59 if (!s || !feats) {
60 return;
61 }
63 if (!p) {
64 return;
65 }
66 p->pService = s;
67 p->pFeatures = feats;
68 InternalService* displaced = nullptr;
69 {
71 auto old = m_Services.lookup(serviceName);
72 if (old.hasValue()) {
73 displaced = old.value();
74 displaced->operations.close();
75 }
76 m_Services.insert(serviceName, p);
77 }
78 if (displaced) {
79 displaced->operations.wait();
80 delete displaced;
81 }
82}
83
84void ServiceManager::removeService(const String& serviceName) {
85 InternalService* service = nullptr;
86 {
88 auto result = m_Services.lookup(serviceName);
89 if (!result.hasValue()) {
90 return;
91 }
92 service = result.value();
93 m_Services.remove(serviceName);
94 service->operations.close();
95 }
96 service->operations.wait();
97 delete service;
98}
99
102 RadixTree<InternalService*>::LookupType result = m_Services.lookup(serviceName);
103 if (result.hasValue()) {
104 return result.value()->pService;
105 } else {
106 return 0;
107 }
108}
109
110bool ServiceManager::tryGetService(const String& serviceName, Service*& service,
111 ServiceFeatures*& features) {
112 service = nullptr;
113 features = nullptr;
115 if (!m_Lock.tryAcquire()) {
116 return false;
117 }
118 auto result = m_Services.lookup(serviceName);
119 if (result.hasValue()) {
120 service = result.value()->pService;
121 features = result.value()->pFeatures;
122 }
123 m_Lock.release();
124 return service && features;
125}
126
127bool ServiceManager::serve(const String& serviceName, ServiceFeatures::Type type, void* data,
128 size_t dataLen) {
129 OperationBarrier::Lease operation;
130 Service* service = nullptr;
131 ServiceFeatures* features = nullptr;
132 {
134 auto result = m_Services.lookup(serviceName);
135 if (!result.hasValue() || !result.value()->operations.tryAcquire(operation)) {
136 return false;
137 }
138 service = result.value()->pService;
139 features = result.value()->pFeatures;
140 }
141 return features->provides(type) && service->serve(type, data, dataLen);
142}
Definition List.h:61
static bool getInterrupts()
void release(size_t n=1)
Definition Semaphore.cc:549
bool tryAcquire(size_t n=1)
Definition Semaphore.cc:484
virtual bool provides(Type service)
Service * pService
The Service itself.
ServiceFeatures * pFeatures
Service operation enumeration.
bool tryGetService(const String &serviceName, Service *&service, ServiceFeatures *&features)
Service * getService(const String &serviceName)
void addService(const String &serviceName, Service *s, ServiceFeatures *feats)
bool serve(const String &serviceName, ServiceFeatures::Type type, void *data, size_t dataLen)
void removeService(const String &serviceName)
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
void pushBack(const T &value)
Definition List.h:216