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