- Implement Trigger method to allow buffers
- Identation, 80/90, tabs & whitespaces git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32788 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,148 +14,164 @@ template <
|
|||||||
size_t MAX_MESSAGE_DEEP = 16,
|
size_t MAX_MESSAGE_DEEP = 16,
|
||||||
uint32 PRIORITY = B_URGENT_DISPLAY_PRIORITY>
|
uint32 PRIORITY = B_URGENT_DISPLAY_PRIORITY>
|
||||||
class PortListener {
|
class PortListener {
|
||||||
public:
|
public:
|
||||||
typedef status_t (*port_listener_func)(TYPE*, int32, size_t);
|
typedef status_t (*port_listener_func)(TYPE*, int32, size_t);
|
||||||
|
|
||||||
PortListener(const char* name, port_listener_func handler)
|
PortListener(const char* name, port_listener_func handler)
|
||||||
{
|
{
|
||||||
fInformation.func = handler;
|
fInformation.func = handler;
|
||||||
fInformation.port = &fPort;
|
fInformation.port = &fPort;
|
||||||
|
|
||||||
InitCheck();
|
InitCheck();
|
||||||
fPortName = strdup(name);
|
fPortName = strdup(name);
|
||||||
fThreadName = strdup(name);
|
fThreadName = strdup(name);
|
||||||
fThreadName = strcat(fThreadName, " thread");
|
fThreadName = strcat(fThreadName, " thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~PortListener()
|
~PortListener()
|
||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
close_port(fPort);
|
close_port(fPort);
|
||||||
// Closing the port should provoke the thread to finish
|
// Closing the port should provoke the thread to finish
|
||||||
wait_for_thread(fThread, &status);
|
wait_for_thread(fThread, &status);
|
||||||
|
|
||||||
delete fThreadName;
|
delete fThreadName;
|
||||||
delete fPortName;
|
delete fPortName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t TriggerCode(int32 code)
|
status_t Trigger(int32 code)
|
||||||
{
|
{
|
||||||
return write_port(fPort, code, NULL, 0);
|
return write_port(fPort, code, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t Trigger(int32 code, TYPE* buffer, size_t size = 0)
|
||||||
|
{
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return write_port(fPort, code, buffer, sizeof(TYPE));
|
||||||
|
else
|
||||||
|
return write_port(fPort, code, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t InitCheck()
|
||||||
|
{
|
||||||
|
// Create Port
|
||||||
|
fPort = find_port(fPortName);
|
||||||
|
if (fPort == B_NAME_NOT_FOUND) {
|
||||||
|
fPort = create_port(MAX_MESSAGE_DEEP, fPortName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fPort < B_OK)
|
||||||
|
return fPort;
|
||||||
|
|
||||||
status_t InitCheck()
|
// Create Thread
|
||||||
{
|
|
||||||
// Create Port
|
|
||||||
fPort = find_port(fPortName);
|
|
||||||
if (fPort == B_NAME_NOT_FOUND) {
|
|
||||||
fPort = create_port(MAX_MESSAGE_DEEP, fPortName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fPort < B_OK)
|
fThread = find_thread(fThreadName);
|
||||||
return fPort;
|
if (fThread < B_OK) {
|
||||||
|
|
||||||
// Create Thread
|
|
||||||
|
|
||||||
fThread = find_thread(fThreadName);
|
|
||||||
if (fThread < B_OK) {
|
|
||||||
#ifdef KERNEL_LAND
|
#ifdef KERNEL_LAND
|
||||||
fThread = spawn_kernel_thread((thread_func)&PortListener<TYPE,MAX_MESSAGE_SIZE,
|
fThread = spawn_kernel_thread((thread_func)&PortListener<TYPE,
|
||||||
MAX_MESSAGE_DEEP, PRIORITY>::threadFunction, fThreadName, PRIORITY, &fInformation);
|
MAX_MESSAGE_SIZE, MAX_MESSAGE_DEEP, PRIORITY>::threadFunction,
|
||||||
|
fThreadName, PRIORITY, &fInformation);
|
||||||
#else
|
#else
|
||||||
fThread = spawn_thread((thread_func)&PortListener<TYPE,MAX_MESSAGE_SIZE,
|
fThread = spawn_thread((thread_func)&PortListener<TYPE,
|
||||||
MAX_MESSAGE_DEEP, PRIORITY>::threadFunction, fThreadName, PRIORITY, &fInformation);
|
MAX_MESSAGE_SIZE, MAX_MESSAGE_DEEP, PRIORITY>::threadFunction,
|
||||||
|
fThreadName, PRIORITY, &fInformation);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fThread < B_OK)
|
||||||
|
return fThread;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t Launch()
|
||||||
|
{
|
||||||
|
status_t check = InitCheck();
|
||||||
|
|
||||||
|
if (check < B_OK)
|
||||||
|
return check;
|
||||||
|
|
||||||
|
return resume_thread(fThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t Stop()
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
close_port(fPort);
|
||||||
|
// Closing the port should provoke the thread to finish
|
||||||
|
wait_for_thread(fThread, &status);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct PortListenerInfo {
|
||||||
|
port_id* port;
|
||||||
|
port_listener_func func;
|
||||||
|
} fInformation;
|
||||||
|
|
||||||
|
port_id fPort;
|
||||||
|
thread_id fThread;
|
||||||
|
char* fThreadName;
|
||||||
|
char* fPortName;
|
||||||
|
|
||||||
|
static int32 threadFunction(void* data)
|
||||||
|
{
|
||||||
|
ssize_t ssizePort;
|
||||||
|
ssize_t ssizeRead;
|
||||||
|
status_t status = B_OK;
|
||||||
|
int32 code;
|
||||||
|
|
||||||
|
port_id* port = ((struct PortListenerInfo*)data)->port;
|
||||||
|
port_listener_func handler = ((struct PortListenerInfo*)data)->func;
|
||||||
|
|
||||||
|
|
||||||
|
TYPE* buffer = (TYPE*)malloc(MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
|
while ((ssizePort = port_buffer_size(*port)) != B_BAD_PORT_ID) {
|
||||||
|
|
||||||
|
if (ssizePort <= 0) {
|
||||||
|
snooze(500*1000);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fThread < B_OK)
|
if (ssizePort > MAX_MESSAGE_SIZE) {
|
||||||
return fThread;
|
snooze(500*1000);
|
||||||
|
continue;
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t Launch()
|
|
||||||
{
|
|
||||||
status_t check = InitCheck();
|
|
||||||
|
|
||||||
if (check < B_OK)
|
|
||||||
return check;
|
|
||||||
|
|
||||||
return resume_thread(fThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t Stop()
|
|
||||||
{
|
|
||||||
status_t status;
|
|
||||||
wait_for_thread(fThread, &status);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct PortListenerInfo {
|
|
||||||
port_id* port;
|
|
||||||
port_listener_func func;
|
|
||||||
} fInformation;
|
|
||||||
|
|
||||||
port_id fPort;
|
|
||||||
thread_id fThread;
|
|
||||||
char* fThreadName;
|
|
||||||
char* fPortName;
|
|
||||||
|
|
||||||
static int32 threadFunction(void* data)
|
|
||||||
{
|
|
||||||
ssize_t ssizePort;
|
|
||||||
ssize_t ssizeRead;
|
|
||||||
status_t status = B_OK;
|
|
||||||
int32 code;
|
|
||||||
|
|
||||||
port_id* port = ((struct PortListenerInfo*)data)->port;
|
|
||||||
port_listener_func handler = ((struct PortListenerInfo*)data)->func;
|
|
||||||
|
|
||||||
|
|
||||||
TYPE* buffer = (TYPE*)malloc(MAX_MESSAGE_SIZE);
|
|
||||||
|
|
||||||
while ((ssizePort = port_buffer_size(*port)) != B_BAD_PORT_ID) {
|
|
||||||
|
|
||||||
if (ssizePort <= 0) {
|
|
||||||
snooze(500*1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ssizePort > MAX_MESSAGE_SIZE) {
|
|
||||||
snooze(500*1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssizeRead = read_port(*port, &code, (void*)buffer, ssizePort);
|
|
||||||
|
|
||||||
if (ssizeRead != ssizePort)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
status = handler(buffer, code, ssizePort);
|
|
||||||
|
|
||||||
if (status != B_OK)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buffer);
|
ssizeRead = read_port(*port, &code, (void*)buffer, ssizePort);
|
||||||
|
|
||||||
if (ssizePort == B_BAD_PORT_ID) // the port disappeared
|
if (ssizeRead != ssizePort)
|
||||||
return ssizePort;
|
continue;
|
||||||
|
|
||||||
return status;
|
status = handler(buffer, code, ssizePort);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
if (ssizePort == B_BAD_PORT_ID) // the port disappeared
|
||||||
|
return ssizePort;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
}; // PortListener
|
}; // PortListener
|
||||||
|
|
||||||
#endif // PORTLISTENER_H_
|
#endif // PORTLISTENER_H_
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user