Resolved race condition in methode Go of dialog windows.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10276 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* DialogWindow.h
|
||||||
|
* Copyright 2004 Michael Pfeiffer. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DIALOG_WINDOW_H
|
||||||
|
#define __DIALOG_WINDOW_H
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
class DialogWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
DialogWindow(BRect frame,
|
||||||
|
const char *title,
|
||||||
|
window_type type,
|
||||||
|
uint32 flags,
|
||||||
|
uint32 workspace = B_CURRENT_WORKSPACE);
|
||||||
|
|
||||||
|
DialogWindow(BRect frame,
|
||||||
|
const char *title,
|
||||||
|
window_look look,
|
||||||
|
window_feel feel,
|
||||||
|
uint32 flags,
|
||||||
|
uint32 workspace = B_CURRENT_WORKSPACE);
|
||||||
|
|
||||||
|
status_t Go();
|
||||||
|
|
||||||
|
void SetResult(status_t result);
|
||||||
|
|
||||||
|
void MessageReceived(BMessage* msg);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kGetThreadId = 'dwti' // request thread id from window
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t fPreviousResult; // holds the result as long as fResult == NULL
|
||||||
|
volatile status_t *fResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,16 +7,16 @@
|
|||||||
#define __JOBSETUPDLG_H
|
#define __JOBSETUPDLG_H
|
||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
#include <Window.h>
|
#include "DialogWindow.h"
|
||||||
|
|
||||||
#include "JobData.h"
|
#include "JobData.h"
|
||||||
#include "Halftone.h"
|
#include "Halftone.h"
|
||||||
|
#include "JSDSlider.h"
|
||||||
|
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class BRadioButton;
|
class BRadioButton;
|
||||||
class BCheckBox;
|
class BCheckBox;
|
||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
class BSlider;
|
|
||||||
class JobData;
|
class JobData;
|
||||||
class PrinterData;
|
class PrinterData;
|
||||||
class PrinterCap;
|
class PrinterCap;
|
||||||
@@ -45,8 +45,8 @@ private:
|
|||||||
const PrinterCap *fPrinterCap;
|
const PrinterCap *fPrinterCap;
|
||||||
BPopUpMenu *fColorType;
|
BPopUpMenu *fColorType;
|
||||||
BPopUpMenu *fDitherType;
|
BPopUpMenu *fDitherType;
|
||||||
BSlider *fGamma;
|
JSDSlider *fGamma;
|
||||||
BSlider *fInkDensity;
|
JSDSlider *fInkDensity;
|
||||||
HalftoneView *fHalftone;
|
HalftoneView *fHalftone;
|
||||||
BRadioButton *fAll;
|
BRadioButton *fAll;
|
||||||
BCheckBox *fCollate;
|
BCheckBox *fCollate;
|
||||||
@@ -56,17 +56,13 @@ private:
|
|||||||
BPopUpMenu *fNup;
|
BPopUpMenu *fNup;
|
||||||
};
|
};
|
||||||
|
|
||||||
class JobSetupDlg : public BWindow {
|
class JobSetupDlg : public DialogWindow {
|
||||||
public:
|
public:
|
||||||
JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap);
|
JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap);
|
||||||
~JobSetupDlg();
|
~JobSetupDlg();
|
||||||
virtual bool QuitRequested();
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
int Go();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fResult;
|
|
||||||
long fSemaphore;
|
|
||||||
BMessageFilter *fFilter;
|
BMessageFilter *fFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#define __PAGESETUPDLG_H
|
#define __PAGESETUPDLG_H
|
||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
#include <Window.h>
|
#include "DialogWindow.h"
|
||||||
|
|
||||||
class BRadioButton;
|
class BRadioButton;
|
||||||
class BPopUpMenu;
|
class BPopUpMenu;
|
||||||
@@ -31,17 +31,12 @@ private:
|
|||||||
BPopUpMenu *fResolution;
|
BPopUpMenu *fResolution;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageSetupDlg : public BWindow {
|
class PageSetupDlg : public DialogWindow {
|
||||||
public:
|
public:
|
||||||
PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap);
|
PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap);
|
||||||
~PageSetupDlg();
|
|
||||||
virtual bool QuitRequested();
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
int Go();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fResult;
|
|
||||||
long fSemaphore;
|
|
||||||
BMessageFilter *fFilter;
|
BMessageFilter *fFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* DialogWindow.h
|
||||||
|
* Copyright 2004 Michael Pfeiffer. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DialogWindow.h"
|
||||||
|
|
||||||
|
#include <Messenger.h>
|
||||||
|
|
||||||
|
DialogWindow::DialogWindow(BRect frame,
|
||||||
|
const char *title,
|
||||||
|
window_type type,
|
||||||
|
uint32 flags,
|
||||||
|
uint32 workspace)
|
||||||
|
: BWindow(frame, title, type, flags, workspace)
|
||||||
|
, fPreviousResult(B_OK)
|
||||||
|
, fResult(NULL)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogWindow::DialogWindow(BRect frame,
|
||||||
|
const char *title,
|
||||||
|
window_look look,
|
||||||
|
window_feel feel,
|
||||||
|
uint32 flags,
|
||||||
|
uint32 workspace)
|
||||||
|
: BWindow(frame, title, look, feel, flags, workspace)
|
||||||
|
, fPreviousResult(B_OK)
|
||||||
|
, fResult(NULL)
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogWindow::MessageReceived(BMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg->what == kGetThreadId) {
|
||||||
|
BMessage reply;
|
||||||
|
reply.AddInt32("thread_id", Thread());
|
||||||
|
msg->SendReply(&reply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BWindow::MessageReceived(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t DialogWindow::Go()
|
||||||
|
{
|
||||||
|
BMessenger messenger(this, this);
|
||||||
|
// store result in local variable and
|
||||||
|
// initialize it with previous result
|
||||||
|
volatile status_t result = fPreviousResult;
|
||||||
|
// new results are stored on the stack
|
||||||
|
fResult = &result;
|
||||||
|
|
||||||
|
// show the window
|
||||||
|
Show();
|
||||||
|
// at this point we must not access member variables,
|
||||||
|
// because this object (the window) could already be deleted.
|
||||||
|
|
||||||
|
// get thread id of window thread
|
||||||
|
BMessage reply;
|
||||||
|
if (messenger.SendMessage(kGetThreadId, &reply) != B_OK) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
thread_id windowThread;
|
||||||
|
if (reply.FindInt32("thread_id", &windowThread) != B_OK) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for window thread to die
|
||||||
|
// The window thread will crash if the image holding the
|
||||||
|
// code used by the window thread is unloaded while the thread is
|
||||||
|
// still running!!!
|
||||||
|
status_t status = B_ERROR;
|
||||||
|
wait_for_thread(windowThread, &status);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogWindow::SetResult(status_t result)
|
||||||
|
{
|
||||||
|
if (fResult != NULL) {
|
||||||
|
*fResult = result;
|
||||||
|
} else {
|
||||||
|
fPreviousResult = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "HalftoneView.h"
|
#include "HalftoneView.h"
|
||||||
#include "JobSetupDlg.h"
|
#include "JobSetupDlg.h"
|
||||||
#include "JobData.h"
|
#include "JobData.h"
|
||||||
|
#include "JSDSlider.h"
|
||||||
#include "PrinterData.h"
|
#include "PrinterData.h"
|
||||||
#include "PrinterCap.h"
|
#include "PrinterCap.h"
|
||||||
#include "DbgMsg.h"
|
#include "DbgMsg.h"
|
||||||
@@ -439,7 +440,8 @@ void JobSetupView::AttachedToWindow()
|
|||||||
fHalftone->preview(fJobData->getGamma(), fJobData->getInkDensity(), fJobData->getDitherType(), fJobData->getColor() == JobData::kColor);
|
fHalftone->preview(fJobData->getGamma(), fJobData->getInkDensity(), fJobData->getDitherType(), fJobData->getColor() == JobData::kColor);
|
||||||
|
|
||||||
/* gamma */
|
/* gamma */
|
||||||
fGamma = new BSlider(gamma_rect, "", "Gamma", new BMessage(kMsgQuality), -300, 300);
|
fGamma = new JSDSlider(gamma_rect, "gamma", "Gamma", new BMessage(kMsgQuality), -300, 300, B_BLOCK_THUMB);
|
||||||
|
|
||||||
fGamma->SetLimitLabels("Brighter", "Darker");
|
fGamma->SetLimitLabels("Brighter", "Darker");
|
||||||
fGamma->SetValue(100 * log(fJobData->getGamma()) / log(2.0));
|
fGamma->SetValue(100 * log(fJobData->getGamma()) / log(2.0));
|
||||||
fGamma->SetHashMarks(B_HASH_MARKS_BOTH);
|
fGamma->SetHashMarks(B_HASH_MARKS_BOTH);
|
||||||
@@ -449,7 +451,8 @@ void JobSetupView::AttachedToWindow()
|
|||||||
fGamma->SetTarget(this);
|
fGamma->SetTarget(this);
|
||||||
|
|
||||||
/* ink density */
|
/* ink density */
|
||||||
fInkDensity = new BSlider(ink_density_rect, "", "Ink Density", new BMessage(kMsgQuality), 0, 127);
|
fInkDensity = new JSDSlider(ink_density_rect, "inkDensity", "Ink Density", new BMessage(kMsgQuality), 0, 127, B_BLOCK_THUMB);
|
||||||
|
|
||||||
fInkDensity->SetLimitLabels("Max", "Min");
|
fInkDensity->SetLimitLabels("Max", "Min");
|
||||||
fInkDensity->SetValue((int32)fJobData->getInkDensity());
|
fInkDensity->SetValue((int32)fJobData->getInkDensity());
|
||||||
fInkDensity->SetHashMarks(B_HASH_MARKS_TOP);
|
fInkDensity->SetHashMarks(B_HASH_MARKS_TOP);
|
||||||
@@ -771,70 +774,44 @@ filter_result PrintKeyFilter(BMessage *msg, BHandler **target, BMessageFilter *f
|
|||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
||||||
JobSetupDlg::JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap)
|
JobSetupDlg::JobSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap)
|
||||||
: BWindow(BRect(100, 100, 100 + PRINT_WIDTH, 100 + PRINT_HEIGHT),
|
: DialogWindow(BRect(100, 100, 100 + PRINT_WIDTH, 100 + PRINT_HEIGHT),
|
||||||
"PrintJob Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
"PrintJob Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
||||||
B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||||
{
|
{
|
||||||
fResult = 0;
|
|
||||||
/*
|
/*
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
oss << printer_data->get_printer_name() << " Print";
|
oss << printer_data->get_printer_name() << " Print";
|
||||||
SetTitle(oss.str().c_str());
|
SetTitle(oss.str().c_str());
|
||||||
*/
|
*/
|
||||||
Lock();
|
SetResult(B_ERROR);
|
||||||
|
|
||||||
JobSetupView *view = new JobSetupView(Bounds(), job_data, printer_data, printer_cap);
|
JobSetupView *view = new JobSetupView(Bounds(), job_data, printer_data, printer_cap);
|
||||||
AddChild(view);
|
AddChild(view);
|
||||||
fFilter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN, &PrintKeyFilter);
|
fFilter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, B_KEY_DOWN, &PrintKeyFilter);
|
||||||
AddCommonFilter(fFilter);
|
AddCommonFilter(fFilter);
|
||||||
Unlock();
|
|
||||||
|
|
||||||
fSemaphore = create_sem(0, "JobSetupSem");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JobSetupDlg::~JobSetupDlg()
|
JobSetupDlg::~JobSetupDlg()
|
||||||
{
|
{
|
||||||
Lock();
|
|
||||||
RemoveCommonFilter(fFilter);
|
RemoveCommonFilter(fFilter);
|
||||||
Unlock();
|
|
||||||
delete fFilter;
|
delete fFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JobSetupDlg::QuitRequested()
|
|
||||||
{
|
|
||||||
fResult = B_ERROR;
|
|
||||||
release_sem(fSemaphore);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JobSetupDlg::MessageReceived(BMessage *msg)
|
void JobSetupDlg::MessageReceived(BMessage *msg)
|
||||||
{
|
{
|
||||||
switch (msg->what) {
|
switch (msg->what) {
|
||||||
case kMsgOK:
|
case kMsgOK:
|
||||||
Lock();
|
|
||||||
((JobSetupView *)ChildAt(0))->UpdateJobData();
|
((JobSetupView *)ChildAt(0))->UpdateJobData();
|
||||||
Unlock();
|
SetResult(B_NO_ERROR);
|
||||||
fResult = B_NO_ERROR;
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
release_sem(fSemaphore);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMsgCancel:
|
case kMsgCancel:
|
||||||
fResult = B_ERROR;
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
release_sem(fSemaphore);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(msg);
|
DialogWindow::MessageReceived(msg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int JobSetupDlg::Go()
|
|
||||||
{
|
|
||||||
Show();
|
|
||||||
acquire_sem(fSemaphore);
|
|
||||||
delete_sem(fSemaphore);
|
|
||||||
int value = fResult;
|
|
||||||
Lock();
|
|
||||||
Quit();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -270,34 +270,20 @@ bool PageSetupView::UpdateJobData()
|
|||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
||||||
PageSetupDlg::PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap)
|
PageSetupDlg::PageSetupDlg(JobData *job_data, PrinterData *printer_data, const PrinterCap *printer_cap)
|
||||||
: BWindow(BRect(100, 100, 100 + PAGESETUP_WIDTH, 100 + PAGESETUP_HEIGHT),
|
: DialogWindow(BRect(100, 100, 100 + PAGESETUP_WIDTH, 100 + PAGESETUP_HEIGHT),
|
||||||
"Page Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
"Page Setup", B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
|
||||||
B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE)
|
B_NOT_RESIZABLE | B_NOT_MINIMIZABLE | B_NOT_ZOOMABLE)
|
||||||
{
|
{
|
||||||
fResult = 0;
|
|
||||||
/*
|
/*
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
oss << printer_data->get_printer_name() << " Setup";
|
oss << printer_data->get_printer_name() << " Setup";
|
||||||
SetTitle(title.str().c_str());
|
SetTitle(title.str().c_str());
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Lock();
|
|
||||||
PageSetupView *view = new PageSetupView(Bounds(), job_data, printer_data, printer_cap);
|
PageSetupView *view = new PageSetupView(Bounds(), job_data, printer_data, printer_cap);
|
||||||
AddChild(view);
|
AddChild(view);
|
||||||
Unlock();
|
|
||||||
|
SetResult(B_ERROR);
|
||||||
fSemaphore = create_sem(0, "PageSetupSem");
|
|
||||||
}
|
|
||||||
|
|
||||||
PageSetupDlg::~PageSetupDlg()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PageSetupDlg::QuitRequested()
|
|
||||||
{
|
|
||||||
fResult = B_ERROR;
|
|
||||||
release_sem(fSemaphore);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageSetupDlg::MessageReceived(BMessage *msg)
|
void PageSetupDlg::MessageReceived(BMessage *msg)
|
||||||
@@ -307,28 +293,16 @@ void PageSetupDlg::MessageReceived(BMessage *msg)
|
|||||||
Lock();
|
Lock();
|
||||||
((PageSetupView *)ChildAt(0))->UpdateJobData();
|
((PageSetupView *)ChildAt(0))->UpdateJobData();
|
||||||
Unlock();
|
Unlock();
|
||||||
fResult = B_NO_ERROR;
|
SetResult(B_NO_ERROR);
|
||||||
release_sem(fSemaphore);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMsgCancel:
|
case kMsgCancel:
|
||||||
fResult = B_ERROR;
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
release_sem(fSemaphore);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(msg);
|
DialogWindow::MessageReceived(msg);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PageSetupDlg::Go()
|
|
||||||
{
|
|
||||||
Show();
|
|
||||||
acquire_sem(fSemaphore);
|
|
||||||
delete_sem(fSemaphore);
|
|
||||||
int value = fResult;
|
|
||||||
Lock();
|
|
||||||
Quit();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user