Changed the report system to use threads.

Unfortunately I need threads for this (because reports will be used in Up()/Down() and always creating a reply port is not very nice).
Does anyone have a good send/receive_data_etc() implementation? :) I hope our kernel will get that functionality.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4085 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-07-26 18:17:26 +00:00
parent cdb26db4b8
commit ff3b40e0da
5 changed files with 78 additions and 27 deletions

View File

@ -105,10 +105,10 @@ class PPPInterface {
bool Down();
bool IsUp() const;
void EnableReports(PPP_REPORT_TYPE type, port_id port,
void EnableReports(PPP_REPORT_TYPE type, thread_id thread,
int32 flags = PPP_NO_REPORT_FLAGS);
void DisableReports(PPP_REPORT_TYPE type, port_id port);
bool DoesReport(PPP_REPORT_TYPE type, port_id port);
void DisableReports(PPP_REPORT_TYPE type, thread_id thread);
bool DoesReport(PPP_REPORT_TYPE type, thread_id thread);
bool Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length);
// returns false if reply was bad (or an error occured)
@ -158,8 +158,6 @@ class PPPInterface {
List<ppp_module_info*> fModules;
List<ppp_report_request> fReportRequests;
port_id fPort;
BLocker& fLock;
};

View File

@ -32,7 +32,6 @@ enum PPP_CONNECTION_REPORT_CODES {
};
typedef struct ppp_report_packet {
port_id port;
int32 type;
int32 code;
uint8 len;
@ -44,7 +43,7 @@ typedef struct ppp_report_packet {
//***********
// private
//***********
#define PPP_REPORT_TIMEOUT 10000
#define PPP_REPORT_TIMEOUT 10
typedef struct ppp_report_request {
port_id port;

View File

@ -32,8 +32,6 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
if(get_module(PPP_MANAGER_MODULE_NAME, (module_info**) &fManager) != B_OK)
fManager = NULL;
fPort = create_port(0, "PPP: reply port");
// are we a multilink subinterface?
if(parent && parent->IsMultilink()) {
fParent = parent;
@ -94,7 +92,6 @@ PPPInterface::~PPPInterface()
// put all modules (in fModules)
put_module((module_info**) &fManager);
delete_port(fPort);
}
@ -108,7 +105,7 @@ PPPInterface::Delete()
status_t
PPPInterface::InitCheck() const
{
if(!fSettings || !fManager || fPort < 0)
if(!fSettings || !fManager)
return B_ERROR;
// sub-interfaces should have a device
@ -513,14 +510,14 @@ PPPInterface::IsUp() const
void
PPPInterface::EnableReports(PPP_REPORT_TYPE type, port_id port,
PPPInterface::EnableReports(PPP_REPORT_TYPE type, thread_id thread,
int32 flags = PPP_NO_REPORT_FLAGS)
{
LockerHelper locker(fLock);
ppp_report_request request;
request.type = type;
request.port = port;
request.thread = thread;
request.flags = flags;
fReportRequests.AddItem(request);
@ -528,14 +525,14 @@ PPPInterface::EnableReports(PPP_REPORT_TYPE type, port_id port,
void
PPPInterface::DisableReports(PPP_REPORT_TYPE type, port_id port)
PPPInterface::DisableReports(PPP_REPORT_TYPE type, thread_id thread)
{
LockerHelper locker(fLock);
for(int32 i = 0; i < fReportRequests.CountItems(); i++) {
ppp_report_request& request = fReportRequests.ItemAt(i);
if(request.port != port)
if(request.thread != thread)
continue;
if(report.type == type)
@ -545,14 +542,14 @@ PPPInterface::DisableReports(PPP_REPORT_TYPE type, port_id port)
bool
PPPInterface::DoesReport(PPP_REPORT_TYPE type, port_id port)
PPPInterface::DoesReport(PPP_REPORT_TYPE type, thread_id thread)
{
LockerHelper locker(fLock);
for(int32 i = 0; i < fReportRequests.CountItems(); i++) {
ppp_report_request& request = fReportRequests.ItemAt(i);
if(request.port == port && request.type == type)
if(request.thread == thread && request.type == type)
return true;
}
@ -563,7 +560,7 @@ PPPInterface::DoesReport(PPP_REPORT_TYPE type, port_id port)
bool
PPPInterface::Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length)
{
if(length > PPP_REPORT_DATA_LIMIT || fPort < 0)
if(length > PPP_REPORT_DATA_LIMIT)
return false;
if(fReportRequests.CountItems() == 0)
@ -575,10 +572,10 @@ PPPInterface::Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length)
LockerHelper locker(fLock);
int32 code, query, result;
bool successful = true;
thread_id sender;
bool acceptable = true;
report_packet report;
report.port = fPort;
report.type = type;
report.code = code;
report.length = length;
@ -587,18 +584,18 @@ PPPInterface::Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length)
for(int32 index = 0; index < fReportRequests.CountItems(); index++) {
ppp_report_request& request = fReportRequests.ItemAt(index);
result = write_port_etc(request.port, PPP_REPORT_CODE, &report,
sizeof(report), B_TIMEOUT, PPP_REPORT_TIMEOUT);
result = send_data_with_timeout(request.port, PPP_REPORT_CODE, &report,
sizeof(report), PPP_REPORT_TIMEOUT);
if(result == B_BAD_PORT_ID) {
if(result == B_BAD_THREAD_ID || result == B_NO_MEMORY) {
fReportRequests.RemoveItem(request);
--index;
continue;
} else if(result == B_OK) {
if(request.flags & PPP_WAIT_FOR_REPLY) {
result = read_port_etc(fPort, &code, NULL, 0,
B_TIMEOUT, PPP_REPORT_TIMEOUT);
if(result == 0 && code != B_OK)
result = receive_data_with_timeout(fPort, &code, NULL, 0,
PPP_REPORT_TIMEOUT);
if(result == B_OK && code != B_OK)
successful = false;
}
}
@ -609,7 +606,7 @@ PPPInterface::Report(PPP_REPORT_TYPE type, int32 code, void *data, int32 length)
}
}
return successful;
return acceptable;
}

View File

@ -0,0 +1,43 @@
#include "KPPPUtils.h"
#include <OS.h>
// These are very simple send/receive_data functions with a timeout
// and there is a race condition beween has_data() and send/receive_data().
// Timeouts in ms.
status_t
send_data_with_timeout(thread_id thread, int32 code, void *buffer,
size_t buffer_size, uint32 timeout)
{
int32 tries;
for(tries = 0; tries < timeout; tries++) {
if(has_data(thread))
snooze(1000);
else
return send_data(thread, code, buffer, buffer_size);
}
return B_TIMED_OUT;
}
status_t
receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
size_t buffer_size, uint32 timeout)
{
int32 tries;
for(tries = 0; tries < timeout; tries++) {
if(has_data(find_thread(NULL))) {
snooze(1000);
continue;
}
*code = receive_data(sender, buffer, buffer_size);
return B_OK;
}
return B_TIMED_OUT;
}

View File

@ -0,0 +1,14 @@
#ifndef _K_PPP_UTILS__H
#define _K_PPP_UTILS__H
// These are very simple send/receive_data functions with a timeout
// and there is a race condition beween has_data() and send/receive_data().
// Timeouts in ms.
status_t send_data_with_timeout(thread_id thread, int32 code, void *buffer,
size_t buffer_size, uint32 timeout);
status_t receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
size_t buffer_size, uint32 timeout);
#endif