1 /*
2 * Copyright 2002-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Michael Pfeiffer
7 */
8 #include "ResourceManager.h"
9
10 #include <Debug.h>
11 #include <Autolock.h>
12
Resource(const char * transport,const char * address,const char * connection)13 Resource::Resource(const char* transport, const char* address, const char* connection)
14 : fTransport(transport)
15 , fTransportAddress(address)
16 , fConnection(connection)
17 , fResourceAvailable(0)
18
19 {
20 if (NeedsLocking()) {
21 fResourceAvailable = create_sem(1, "resource");
22 }
23 }
24
25
~Resource()26 Resource::~Resource() {
27 if (fResourceAvailable > 0) delete_sem(fResourceAvailable);
28 }
29
30
31 bool
NeedsLocking()32 Resource::NeedsLocking() {
33 // TODO R2: Provide API to query that information
34 // ATM: Print jobs are not processed sequentially
35 // if the transport add-on is either "Print To File"
36 // or in case of "Preview" printer it
37 // is set on R5 to "NONE" IIRC and the Haiku
38 // preflet sets an empty string.
39 return !(fTransport == "Print to file"
40 || fTransport == "NONE"
41 || fTransport == "");
42 }
43
44
45 bool
Equals(const char * transport,const char * address,const char * connection)46 Resource::Equals(const char* transport, const char* address, const char* connection) {
47 return fTransport == transport &&
48 fTransportAddress == address &&
49 fConnection == connection;
50 }
51
52
53 bool
Lock()54 Resource::Lock() {
55 if (fResourceAvailable > 0) {
56 return acquire_sem(fResourceAvailable) == B_NO_ERROR;
57 }
58 return true;
59 }
60
61
62 void
Unlock()63 Resource::Unlock() {
64 if (fResourceAvailable > 0) {
65 release_sem(fResourceAvailable);
66 }
67 }
68
69
~ResourceManager()70 ResourceManager::~ResourceManager() {
71 ASSERT(fResources.CountItems() == 0);
72 }
73
74
75 Resource*
Find(const char * transport,const char * address,const char * connection)76 ResourceManager::Find(const char* transport, const char* address, const char* connection) {
77 for (int i = 0; i < fResources.CountItems(); i ++) {
78 Resource* r = fResources.ItemAt(i);
79 if (r->Equals(transport, address, connection)) return r;
80 }
81 return NULL;
82 }
83
84
85 Resource*
Allocate(const char * transport,const char * address,const char * connection)86 ResourceManager::Allocate(const char* transport, const char* address, const char* connection) {
87 Resource* r = Find(transport, address, connection);
88 if (r == NULL) {
89 r = new Resource(transport, address, connection);
90 fResources.AddItem(r);
91 } else {
92 r->Acquire();
93 }
94 return r;
95 }
96
97
98 void
Free(Resource * r)99 ResourceManager::Free(Resource* r) {
100 if (r->Release()) {
101 fResources.RemoveItem(r);
102 }
103 }
104