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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user