xref: /haiku/src/servers/print/ResourceManager.cpp (revision 0562493379cd52eb7103531f895f10bb8e77c085)
1 /*
2  * Copyright 2002-2006, Haiku. 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 
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::~Resource() {
26 	if (fResourceAvailable > 0) delete_sem(fResourceAvailable);
27 }
28 
29 bool Resource::NeedsLocking() {
30 	// TODO R2: Provide API to query that information
31 	// ATM: Print jobs are not processed sequentially
32 	// if the transport add-on is either "Print To File"
33 	// or in case of "Preview" printer it
34 	// is set on R5 to "NONE" IIRC and the Haiku
35 	// preflet sets an empty string.
36 	return !(fTransport == "Print To File"
37 		|| fTransport == "NONE"
38 		|| fTransport == "");
39 }
40 
41 bool Resource::Equals(const char* transport, const char* address, const char* connection) {
42 	return fTransport == transport &&
43 			fTransportAddress == address &&
44 			fConnection == connection;
45 }
46 
47 bool Resource::Lock() {
48 	if (fResourceAvailable > 0) {
49 		return acquire_sem(fResourceAvailable) == B_NO_ERROR;
50 	}
51 	return true;
52 }
53 
54 void Resource::Unlock() {
55 	if (fResourceAvailable > 0) {
56 		release_sem(fResourceAvailable);
57 	}
58 }
59 
60 ResourceManager::~ResourceManager() {
61 	ASSERT(fResources.CountItems() == 0);
62 }
63 
64 Resource* ResourceManager::Find(const char* transport, const char* address, const char* connection) {
65 	for (int i = 0; i < fResources.CountItems(); i ++) {
66 		Resource* r = fResources.ItemAt(i);
67 		if (r->Equals(transport, address, connection)) return r;
68 	}
69 	return NULL;
70 }
71 
72 Resource* ResourceManager::Allocate(const char* transport, const char* address, const char* connection) {
73 	Resource* r = Find(transport, address, connection);
74 	if (r == NULL) {
75 		r = new Resource(transport, address, connection);
76 		fResources.AddItem(r);
77 	} else {
78 		r->Acquire();
79 	}
80 	return r;
81 }
82 
83 
84 void ResourceManager::Free(Resource* r) {
85 	if (r->Release()) {
86 		fResources.RemoveItem(r);
87 	}
88 }
89