Fix a thread safety issue in "USB Port" transport.

Now all transports okok'ed the received init message on success.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7867 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin
2004-06-08 22:59:21 +00:00
parent e243c52503
commit bc333ea2ef
7 changed files with 129 additions and 75 deletions
@@ -57,6 +57,7 @@ extern "C" _EXPORT BDataIO * init_transport(BMessage *msg)
if (transport->Ready()) { if (transport->Ready()) {
g_transport = transport; g_transport = transport;
if (msg)
msg->what = 'okok'; msg->what = 'okok';
return g_transport; return g_transport;
}; };
+3
View File
@@ -26,6 +26,9 @@ extern "C" _EXPORT BDataIO *init_transport(BMessage *msg)
exit_transport(); exit_transport();
} }
if (msg)
msg->what = 'okok';
DBGMSG(("< init_transport\n")); DBGMSG(("< init_transport\n"));
return transport; return transport;
} }
+3
View File
@@ -26,6 +26,9 @@ extern "C" _EXPORT BDataIO *init_transport(BMessage *msg)
exit_transport(); exit_transport();
} }
if (msg)
msg->what = 'okok';
DBGMSG(("< init_transport\n")); DBGMSG(("< init_transport\n"));
return transport; return transport;
} }
@@ -56,18 +56,35 @@ ParallelPort::ParallelPort(BDirectory* printer, BMessage* msg)
{ {
char address[80]; char address[80];
char device[B_PATH_NAME_LENGTH]; char device[B_PATH_NAME_LENGTH];
bool bidirectional = true;
int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address));
if (size <= 0 || size >= sizeof(address)) return; if (size <= 0 || size >= sizeof(address)) return;
address[size] = 0; // make sure string is 0-terminated address[size] = 0; // make sure string is 0-terminated
strcat(strcpy(device, "/dev/parallel/"), address); strcat(strcpy(device, "/dev/parallel/"), address);
fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0); fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0);
if (fFile < 0) {
// Try unidirectional access mode
bidirectional = false;
fFile = open(device, O_WRONLY | O_EXCL | O_BINARY, 0);
}
if (fFile < 0)
return;
if (! msg)
// Caller don't care about transport init message output content...
return;
msg->AddBool("bidirectional", bidirectional);
msg->AddString("_parallel/DeviceName", device);
} }
ParallelPort::~ParallelPort() { ParallelPort::~ParallelPort() {
if (InitCheck() == B_OK) { if (InitCheck() == B_OK) {
close(fFile); fFile = -1; close(fFile);
fFile = -1;
} }
} }
@@ -82,6 +99,8 @@ ssize_t ParallelPort::Write(const void* buffer, size_t size) {
BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) {
ParallelPort* transport = new ParallelPort(printer, msg); ParallelPort* transport = new ParallelPort(printer, msg);
if (transport->InitCheck() == B_OK) { if (transport->InitCheck() == B_OK) {
if (msg)
msg->what = 'okok';
return transport; return transport;
} else { } else {
delete transport; return NULL; delete transport; return NULL;
@@ -65,6 +65,7 @@ extern "C" _EXPORT BDataIO * init_transport
file = new BFile(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); file = new BFile(&ref, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if ( file->InitCheck() != B_OK ) { if ( file->InitCheck() != B_OK ) {
if (msg)
msg->what = 'canc'; // Indicates user cancel the panel... msg->what = 'canc'; // Indicates user cancel the panel...
delete file; delete file;
return NULL; return NULL;
@@ -75,9 +76,11 @@ extern "C" _EXPORT BDataIO * init_transport
BPath path; BPath path;
path.SetTo(&ref); path.SetTo(&ref);
if (msg) {
// Print transport add-ons should set to 'okok' the message on success // Print transport add-ons should set to 'okok' the message on success
msg->what = 'okok'; msg->what = 'okok';
msg->AddString("path", path.Path()); // Add path of new choosen file to transport message msg->AddString("path", path.Path()); // Add path of new choosen file to transport message
}
return file; return file;
} }
@@ -56,13 +56,30 @@ SerialPort::SerialPort(BDirectory* printer, BMessage* msg)
{ {
char address[80]; char address[80];
char device[B_PATH_NAME_LENGTH]; char device[B_PATH_NAME_LENGTH];
bool bidirectional = true;
int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address)); unsigned int size = printer->ReadAttr("transport_address", B_STRING_TYPE, 0, address, sizeof(address));
if (size <= 0 || size >= sizeof(address)) return; if (size <= 0 || size >= sizeof(address)) return;
address[size] = 0; // make sure string is 0-terminated address[size] = 0; // make sure string is 0-terminated
strcat(strcpy(device, "/dev/ports/"), address); strcat(strcpy(device, "/dev/ports/"), address);
fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0); fFile = open(device, O_RDWR | O_EXCL | O_BINARY, 0);
if (fFile < 0) {
// Try unidirectional access mode
bidirectional = false;
fFile = open(device, O_WRONLY | O_EXCL | O_BINARY, 0);
}
if (fFile < 0)
return;
if (! msg)
// Caller don't care about transport init message output content...
return;
msg->AddBool("bidirectional", bidirectional);
msg->AddString("_serial/DeviceName", device);
} }
SerialPort::~SerialPort() { SerialPort::~SerialPort() {
@@ -82,6 +99,8 @@ ssize_t SerialPort::Write(const void* buffer, size_t size) {
BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) {
SerialPort* transport = new SerialPort(printer, msg); SerialPort* transport = new SerialPort(printer, msg);
if (transport->InitCheck() == B_OK) { if (transport->InitCheck() == B_OK) {
if (msg)
msg->what = 'okok';
return transport; return transport;
} else { } else {
delete transport; return NULL; delete transport; return NULL;
@@ -65,6 +65,7 @@ class UsbPort : public BDataIO {
BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) { BDataIO* instanciate_transport(BDirectory* printer, BMessage* msg) {
UsbPort* transport = new UsbPort(printer, msg); UsbPort* transport = new UsbPort(printer, msg);
if (transport->IsOk()) { if (transport->IsOk()) {
if (msg)
msg->what = 'okok'; msg->what = 'okok';
return transport; return transport;
} else { } else {
@@ -84,6 +85,7 @@ UsbPort::UsbPort(BDirectory* printer, BMessage *msg)
char *value; char *value;
int ret; int ret;
bool bidirectional = true; bool bidirectional = true;
char *next_token;
// We support only one USB printer, so does BeOS R5. // We support only one USB printer, so does BeOS R5.
fFile = open("/dev/printer/usb/0", O_RDWR | O_EXCL | O_BINARY, 0); fFile = open("/dev/printer/usb/0", O_RDWR | O_EXCL | O_BINARY, 0);
@@ -104,21 +106,25 @@ UsbPort::UsbPort(BDirectory* printer, BMessage *msg)
return; return;
} }
if (! msg)
// Caller don't care about transport init message output content...
return;
// Fill up the message // Fill up the message
msg->AddBool("bidirectional", bidirectional); msg->AddBool("bidirectional", bidirectional);
msg->AddString("device_id", device_id); msg->AddString("device_id", device_id);
// parse and split the device_id string into separate parameters // parse and split the device_id string into separate parameters
desc = strtok(device_id, ":"); desc = strtok_r(device_id, ":", &next_token);
while (desc) { while (desc) {
snprintf(name, sizeof(name), "DEVID:%s", desc); snprintf(name, sizeof(name), "DEVID:%s", desc);
value = strtok(NULL, ";"); value = strtok_r(NULL, ";", &next_token);
if (!value) if (!value)
break; break;
msg->AddString(name, value); msg->AddString(name, value);
// next device descriptor // next device descriptor
desc = strtok(NULL, ":"); desc = strtok_r(NULL, ":", &next_token);
} }
} }