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 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 26 Resource::~Resource() { 27 if (fResourceAvailable > 0) delete_sem(fResourceAvailable); 28 } 29 30 31 bool 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 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 54 Resource::Lock() { 55 if (fResourceAvailable > 0) { 56 return acquire_sem(fResourceAvailable) == B_NO_ERROR; 57 } 58 return true; 59 } 60 61 62 void 63 Resource::Unlock() { 64 if (fResourceAvailable > 0) { 65 release_sem(fResourceAvailable); 66 } 67 } 68 69 70 ResourceManager::~ResourceManager() { 71 ASSERT(fResources.CountItems() == 0); 72 } 73 74 75 Resource* 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* 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 99 ResourceManager::Free(Resource* r) { 100 if (r->Release()) { 101 fResources.RemoveItem(r); 102 } 103 } 104