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