Bug fix for memory leak. BMessage returned by take_job was not deleted.

Clean up.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1202 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer
2002-09-26 23:45:24 +00:00
parent d16c075486
commit 57e88ee89b
3 changed files with 53 additions and 46 deletions
+5 -5
View File
@@ -72,15 +72,15 @@ void Printer::HandleScriptingCommand(BMessage* msg)
switch(msg->what) {
case B_GET_PROPERTY:
if (propName == "Name")
rc = fNode.ReadAttrString(PSRV_PRINTER_ATTR_PRT_NAME, &result);
rc = SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_PRT_NAME, &result);
else if (propName == "TransportAddon")
rc = fNode.ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &result);
rc = SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT, &result);
else if (propName == "TransportConfig")
rc = fNode.ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &result);
rc = SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_TRANSPORT_ADDR, &result);
else if (propName == "PrinterAddon")
rc = fNode.ReadAttrString(PSRV_PRINTER_ATTR_DRV_NAME, &result);
rc = SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_DRV_NAME, &result);
else if (propName == "Comments")
rc = fNode.ReadAttrString(PSRV_PRINTER_ATTR_COMMENTS, &result);
rc = SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_COMMENTS, &result);
else { // If unknown scripting request, let superclas handle it
Inherited::MessageReceived(msg);
break;
+30 -31
View File
@@ -95,7 +95,7 @@ Printer* Printer::Find(dev_t dev, ino_t node)
for (int32 idx=0; idx < sPrinters.CountItems(); idx++) {
Printer* printer = sPrinters.ItemAt(idx);
node_ref ref;
printer->fNode.GetNodeRef(&ref);
printer->SpoolDir()->GetNodeRef(&ref);
if (ref.device == dev && ref.node == node) return printer;
}
@@ -131,39 +131,37 @@ int32 Printer::CountPrinters()
// ---------------------------------------------------------------
Printer::Printer(const BDirectory* node, Resource* res)
: Inherited(B_EMPTY_STRING),
fFolder(*node),
fPrinter(*node),
fResource(res),
fNode(*node),
fSinglePrintThread(true),
fJob(NULL),
fProcessing(0),
fAbort(false)
{
// Set our name to the name of the passed node
BString name;
fNode.ReadAttrString(PSRV_PRINTER_ATTR_PRT_NAME, &name);
SetName(name.String());
// Set our name to the name of the passed node
if (SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_PRT_NAME, &name) == B_OK)
SetName(name.String());
if (name == "Preview") fSinglePrintThread = false;
// Add us to the global list of known printer definitions
sPrinters.AddItem(this);
be_app->AddHandler(this);
}
Printer::~Printer()
{
((PrintServerApp*)be_app)->NotifyPrinterDeletion(fResource);
((PrintServerApp*)be_app)->NotifyPrinterDeletion(this);
}
// Remove printer spooler directory
status_t Printer::Remove()
{
status_t rc = B_OK;
BPath path;
if ((rc=::find_directory(B_USER_PRINTERS_DIRECTORY, &path)) == B_OK) {
sPrinters.RemoveItem(this);
be_app->RemoveHandler(this);
path.Append(Name());
rc = rmdir(path.Path());
}
@@ -226,7 +224,7 @@ status_t Printer::ConfigurePage(BMessage& settings)
if ((rc=get_image_symbol(id, "config_page", B_SYMBOL_TYPE_TEXT, (void**)&func)) == B_OK) {
// call the function and check its result
BMessage* new_settings = (*func)(&fNode, &settings);
BMessage* new_settings = (*func)(SpoolDir(), &settings);
if (new_settings != NULL && new_settings->what != 'baad')
settings = *new_settings;
}
@@ -261,7 +259,7 @@ status_t Printer::ConfigureJob(BMessage& settings)
if ((rc=get_image_symbol(id, "config_job", B_SYMBOL_TYPE_TEXT, (void**)&func)) == B_OK) {
// call the function and check its result
BMessage* new_settings = (*func)(&fNode, &settings);
BMessage* new_settings = (*func)(SpoolDir(), &settings);
if ((new_settings != NULL) && (new_settings->what != 'baad'))
settings = *new_settings;
else
@@ -309,7 +307,7 @@ status_t Printer::LoadPrinterAddon(image_id& id)
status_t rc;
BPath path;
if ((rc=fNode.ReadAttrString(PSRV_PRINTER_ATTR_DRV_NAME, &drName)) == B_OK) {
if ((rc=SpoolDir()->ReadAttrString(PSRV_PRINTER_ATTR_DRV_NAME, &drName)) == B_OK) {
// try to locate the driver
if ((rc=::TestForAddonExistence(drName.String(), B_USER_ADDONS_DIRECTORY, "Print", path)) != B_OK) {
if ((rc=::TestForAddonExistence(drName.String(), B_COMMON_ADDONS_DIRECTORY, "Print", path)) != B_OK) {
@@ -349,15 +347,11 @@ void Printer::MessageReceived(BMessage* msg)
}
bool Printer::FindSpooledJob() {
fJob = fFolder.GetNextJob();
fJob = fPrinter.GetNextJob();
if (fJob) fJob->SetPrinter(this);
return fJob;
}
void Printer::CloseJob() {
fJob->Release();
}
status_t Printer::PrintSpooledJob(BFile* spoolFile)
{
take_job_func_t func;
@@ -371,11 +365,14 @@ status_t Printer::PrintSpooledJob(BFile* spoolFile)
// HP PCL3 add-on crashes without it!
BMessage params('_RRC');
params.AddInt32("file", (int32)spoolFile);
params.AddInt32("printer", (int32)&fNode);
params.AddInt32("printer", (int32)SpoolDir());
// call the function and check its result
BMessage* result = (*func)(spoolFile, &fNode, &params);
if (result == NULL || result->what == 'baad')
BMessage* result = (*func)(spoolFile, SpoolDir(), &params);
if (result == NULL || result->what != 'okok')
rc = B_ERROR;
delete result;
}
::unload_add_on(id);
@@ -384,25 +381,27 @@ status_t Printer::PrintSpooledJob(BFile* spoolFile)
return rc;
}
void Printer::PrintThread(Job* job) {
// Wait until resource is available
fResource->Lock();
bool failed = true;
// Can we continue?
if (!fAbort) {
BFile jobFile(&job->EntryRef(), B_READ_WRITE);
print_file_header header;
// Tell the printer to print the spooled job
if (PrintSpooledJob(&jobFile) == B_OK) {
if (jobFile.InitCheck() == B_OK && PrintSpooledJob(&jobFile) == B_OK) {
// Remove spool file if printing was successfull.
job->Remove();
} else {
job->SetStatus(kFailed);
job->Remove(); failed = false;
}
} else {
job->SetStatus(kFailed);
}
fResource->Unlock();
// Set status of spooled job on error
if (failed) job->SetStatus(kFailed);
fResource->Unlock();
job->Release();
atomic_add(&fProcessing, -1);
Release();
// Notify print_server to process next spooled job
be_app_messenger.SendMessage(PSRV_PRINT_SPOOLED_JOB);
}
@@ -412,7 +411,7 @@ status_t Printer::print_thread(void* data) {
return 0;
}
status_t Printer::StartPrintThread() {
void Printer::StartPrintThread() {
Acquire();
thread_id tid = spawn_thread(print_thread, "print", B_NORMAL_PRIORITY, (void*)fJob);
if (tid > 0) {
@@ -420,7 +419,7 @@ status_t Printer::StartPrintThread() {
atomic_add(&fProcessing, 1);
resume_thread(tid);
} else {
CloseJob(); Release();
fJob->Release(); Release();
}
}
+18 -10
View File
@@ -75,12 +75,15 @@ public:
static Printer* At(int32 idx);
static void Remove(Printer* printer);
static int32 CountPrinters();
status_t Remove();
status_t ConfigurePrinter();
status_t ConfigureJob(BMessage& ioSettings);
status_t ConfigurePage(BMessage& ioSettings);
// Try to start processing of next spooled job
void HandleSpooledJob();
// Abort print_thread without processing spooled job
void AbortPrintThread();
void MessageReceived(BMessage* msg);
@@ -90,25 +93,30 @@ public:
void HandleScriptingCommand(BMessage* msg);
BHandler* ResolveSpecifier(BMessage* msg, int32 index, BMessage* spec,
int32 form, const char* prop);
Resource* GetResource() { return fResource; }
private:
status_t LoadPrinterAddon(image_id& id);
Folder fFolder;
Resource* fResource;
BDirectory fNode;
bool fSinglePrintThread;
Job* fJob;
volatile vint32 fProcessing;
bool fAbort;
Folder fPrinter; // the printer spooling directory
Resource* fResource; // the resource required for processing a print job
bool fSinglePrintThread; // is printer add-on allowed to process multiple print job at once
Job* fJob; // the next job to process
vint32 fProcessing; // the current number of processing threads
bool fAbort; // stop processing
static BObjectList<Printer> sPrinters;
// Accessor
BDirectory* SpoolDir() { return fPrinter.GetSpoolDir(); }
// Get next spooled job if any
bool FindSpooledJob();
void CloseJob();
status_t PrintSpooledJob(BFile* spoolFile);
void PrintThread(Job* job);
static status_t print_thread(void* data);
status_t StartPrintThread();
void StartPrintThread();
};
#endif