haiku/src/servers/print/ResourceManager.cpp

104 lines
2.1 KiB
C++

/*
* Copyright 2002-2009, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer
*/
#include "ResourceManager.h"
#include <Debug.h>
#include <Autolock.h>
Resource::Resource(const char* transport, const char* address, const char* connection)
: fTransport(transport)
, fTransportAddress(address)
, fConnection(connection)
, fResourceAvailable(0)
{
if (NeedsLocking()) {
fResourceAvailable = create_sem(1, "resource");
}
}
Resource::~Resource() {
if (fResourceAvailable > 0) delete_sem(fResourceAvailable);
}
bool
Resource::NeedsLocking() {
// TODO R2: Provide API to query that information
// ATM: Print jobs are not processed sequentially
// if the transport add-on is either "Print To File"
// or in case of "Preview" printer it
// is set on R5 to "NONE" IIRC and the Haiku
// preflet sets an empty string.
return !(fTransport == "Print to file"
|| fTransport == "NONE"
|| fTransport == "");
}
bool
Resource::Equals(const char* transport, const char* address, const char* connection) {
return fTransport == transport &&
fTransportAddress == address &&
fConnection == connection;
}
bool
Resource::Lock() {
if (fResourceAvailable > 0) {
return acquire_sem(fResourceAvailable) == B_NO_ERROR;
}
return true;
}
void
Resource::Unlock() {
if (fResourceAvailable > 0) {
release_sem(fResourceAvailable);
}
}
ResourceManager::~ResourceManager() {
ASSERT(fResources.CountItems() == 0);
}
Resource*
ResourceManager::Find(const char* transport, const char* address, const char* connection) {
for (int i = 0; i < fResources.CountItems(); i ++) {
Resource* r = fResources.ItemAt(i);
if (r->Equals(transport, address, connection)) return r;
}
return NULL;
}
Resource*
ResourceManager::Allocate(const char* transport, const char* address, const char* connection) {
Resource* r = Find(transport, address, connection);
if (r == NULL) {
r = new Resource(transport, address, connection);
fResources.AddItem(r);
} else {
r->Acquire();
}
return r;
}
void
ResourceManager::Free(Resource* r) {
if (r->Release()) {
fResources.RemoveItem(r);
}
}