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