From 57e88ee89b6136fe8890cf313e96389b4ab7bb15 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Thu, 26 Sep 2002 23:45:24 +0000 Subject: [PATCH] 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 --- src/servers/print/Printer.Scripting.cpp | 10 ++-- src/servers/print/Printer.cpp | 61 ++++++++++++------------- src/servers/print/Printer.h | 28 ++++++++---- 3 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/servers/print/Printer.Scripting.cpp b/src/servers/print/Printer.Scripting.cpp index 1aab6fb2c0..993d209457 100644 --- a/src/servers/print/Printer.Scripting.cpp +++ b/src/servers/print/Printer.Scripting.cpp @@ -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; diff --git a/src/servers/print/Printer.cpp b/src/servers/print/Printer.cpp index 8f4b7a2f3a..f96a0f890c 100644 --- a/src/servers/print/Printer.cpp +++ b/src/servers/print/Printer.cpp @@ -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, ¶ms); - if (result == NULL || result->what == 'baad') + BMessage* result = (*func)(spoolFile, SpoolDir(), ¶ms); + + 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(); } } diff --git a/src/servers/print/Printer.h b/src/servers/print/Printer.h index 90ad4953f2..a260484671 100644 --- a/src/servers/print/Printer.h +++ b/src/servers/print/Printer.h @@ -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 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