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
13Resource::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
26Resource::~Resource() {
27	if (fResourceAvailable > 0) delete_sem(fResourceAvailable);
28}
29
30
31bool
32Resource::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
45bool
46Resource::Equals(const char* transport, const char* address, const char* connection) {
47	return fTransport == transport &&
48			fTransportAddress == address &&
49			fConnection == connection;
50}
51
52
53bool
54Resource::Lock() {
55	if (fResourceAvailable > 0) {
56		return acquire_sem(fResourceAvailable) == B_NO_ERROR;
57	}
58	return true;
59}
60
61
62void
63Resource::Unlock() {
64	if (fResourceAvailable > 0) {
65		release_sem(fResourceAvailable);
66	}
67}
68
69
70ResourceManager::~ResourceManager() {
71	ASSERT(fResources.CountItems() == 0);
72}
73
74
75Resource*
76ResourceManager::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
85Resource*
86ResourceManager::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
98void
99ResourceManager::Free(Resource* r) {
100	if (r->Release()) {
101		fResources.RemoveItem(r);
102	}
103}
104