* Corrected naming/visibility of the DatagramSocket methods (protected methods
do not get the '_' prefix, only private ones do). * Added a "peek" argument to SocketStatus() (and generally renamed "clone" to "peek" where it made sense). * Implemented the base version of SocketStatus() to return the actual socket error. This enables returning ICMP errors back to the socket user. * Other minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37712 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -114,7 +114,7 @@ public:
|
|||||||
|
|
||||||
status_t Enqueue(net_buffer* buffer);
|
status_t Enqueue(net_buffer* buffer);
|
||||||
net_buffer* Dequeue(bool clone);
|
net_buffer* Dequeue(bool clone);
|
||||||
status_t BlockingDequeue(bool clone, bigtime_t timeout,
|
status_t BlockingDequeue(bool peek, bigtime_t timeout,
|
||||||
net_buffer** _buffer);
|
net_buffer** _buffer);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
@@ -122,24 +122,27 @@ public:
|
|||||||
status_t SocketDequeue(uint32 flags,
|
status_t SocketDequeue(uint32 flags,
|
||||||
net_buffer** _buffer);
|
net_buffer** _buffer);
|
||||||
|
|
||||||
|
bool IsEmpty() const { return fBuffers.IsEmpty(); }
|
||||||
ssize_t AvailableData() const;
|
ssize_t AvailableData() const;
|
||||||
|
|
||||||
void WakeAll();
|
void WakeAll();
|
||||||
|
void NotifyOne();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual status_t _SocketStatus() const;
|
virtual status_t SocketStatus(bool peek) const;
|
||||||
|
|
||||||
|
private:
|
||||||
status_t _Enqueue(net_buffer* buffer);
|
status_t _Enqueue(net_buffer* buffer);
|
||||||
status_t _SocketEnqueue(net_buffer* buffer);
|
status_t _SocketEnqueue(net_buffer* buffer);
|
||||||
net_buffer* _Dequeue(bool clone);
|
net_buffer* _Dequeue(bool peek);
|
||||||
void _Clear();
|
void _Clear();
|
||||||
|
|
||||||
status_t _Wait(bigtime_t timeout);
|
status_t _Wait(bigtime_t timeout);
|
||||||
void _NotifyOneReader(bool notifySocket);
|
void _NotifyOneReader(bool notifySocket);
|
||||||
|
|
||||||
bool _IsEmpty() const { return fBuffers.IsEmpty(); }
|
|
||||||
bigtime_t _SocketTimeout(uint32 flags) const;
|
bigtime_t _SocketTimeout(uint32 flags) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
typedef typename LockingBase::Type LockType;
|
typedef typename LockingBase::Type LockType;
|
||||||
typedef typename LockingBase::AutoLocker AutoLocker;
|
typedef typename LockingBase::AutoLocker AutoLocker;
|
||||||
typedef DoublyLinkedListCLink<net_buffer> NetBufferLink;
|
typedef DoublyLinkedListCLink<net_buffer> NetBufferLink;
|
||||||
@@ -249,27 +252,31 @@ DECL_DATAGRAM_SOCKET(inline net_buffer*)::_Dequeue(bool clone)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DECL_DATAGRAM_SOCKET(inline status_t)::BlockingDequeue(bool clone,
|
DECL_DATAGRAM_SOCKET(inline status_t)::BlockingDequeue(bool peek,
|
||||||
bigtime_t timeout, net_buffer** _buffer)
|
bigtime_t timeout, net_buffer** _buffer)
|
||||||
{
|
{
|
||||||
AutoLocker _(fLock);
|
AutoLocker _(fLock);
|
||||||
|
|
||||||
bool waited = false;
|
bool waited = false;
|
||||||
while (fBuffers.IsEmpty()) {
|
while (fBuffers.IsEmpty()) {
|
||||||
status_t status = _SocketStatus();
|
status_t status = SocketStatus(peek);
|
||||||
if (status < B_OK)
|
if (status != B_OK) {
|
||||||
|
if (peek)
|
||||||
|
_NotifyOneReader(false);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _Wait(timeout);
|
||||||
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if ((status = _Wait(timeout)) < B_OK)
|
|
||||||
return status;
|
|
||||||
waited = true;
|
waited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*_buffer = _Dequeue(clone);
|
*_buffer = _Dequeue(peek);
|
||||||
if (clone && waited) {
|
if (peek && waited) {
|
||||||
// we were signalled there was a new buffer in the
|
// There is a new buffer in the list; but since we are only peeking,
|
||||||
// list; but since we are cloning, notify the next
|
// notify the next waiting reader.
|
||||||
// waiting reader.
|
|
||||||
_NotifyOneReader(false);
|
_NotifyOneReader(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +314,7 @@ DECL_DATAGRAM_SOCKET(inline void)::_Clear()
|
|||||||
DECL_DATAGRAM_SOCKET(inline ssize_t)::AvailableData() const
|
DECL_DATAGRAM_SOCKET(inline ssize_t)::AvailableData() const
|
||||||
{
|
{
|
||||||
AutoLocker _(fLock);
|
AutoLocker _(fLock);
|
||||||
status_t status = _SocketStatus();
|
status_t status = SocketStatus(true);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -315,9 +322,15 @@ DECL_DATAGRAM_SOCKET(inline ssize_t)::AvailableData() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DECL_DATAGRAM_SOCKET(inline status_t)::_SocketStatus() const
|
DECL_DATAGRAM_SOCKET(inline status_t)::SocketStatus(bool peek) const
|
||||||
{
|
{
|
||||||
return B_OK;
|
if (peek)
|
||||||
|
return fSocket->error;
|
||||||
|
|
||||||
|
status_t status = fSocket->error;
|
||||||
|
fSocket->error = B_OK;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -338,14 +351,22 @@ DECL_DATAGRAM_SOCKET(inline void)::WakeAll()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DECL_DATAGRAM_SOCKET(inline void)::NotifyOne()
|
||||||
|
{
|
||||||
|
release_sem_etc(fNotify, 1, B_RELEASE_IF_WAITING_ONLY
|
||||||
|
| B_DO_NOT_RESCHEDULE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DECL_DATAGRAM_SOCKET(inline void)::_NotifyOneReader(bool notifySocket)
|
DECL_DATAGRAM_SOCKET(inline void)::_NotifyOneReader(bool notifySocket)
|
||||||
{
|
{
|
||||||
release_sem_etc(fNotify, 1, B_RELEASE_IF_WAITING_ONLY
|
release_sem_etc(fNotify, 1, B_RELEASE_IF_WAITING_ONLY
|
||||||
| B_DO_NOT_RESCHEDULE);
|
| B_DO_NOT_RESCHEDULE);
|
||||||
|
|
||||||
if (notifySocket)
|
if (notifySocket) {
|
||||||
ModuleBundle::Stack()->notify_socket(fSocket, B_SELECT_READ,
|
ModuleBundle::Stack()->notify_socket(fSocket, B_SELECT_READ,
|
||||||
fCurrentBytes);
|
fCurrentBytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,22 +40,26 @@ typedef DatagramSocket<MutexLocking, LocalStackBundle> LocalDatagramSocket;
|
|||||||
|
|
||||||
class LinkProtocol : public net_protocol, public LocalDatagramSocket {
|
class LinkProtocol : public net_protocol, public LocalDatagramSocket {
|
||||||
public:
|
public:
|
||||||
LinkProtocol(net_socket* socket);
|
LinkProtocol(net_socket* socket);
|
||||||
~LinkProtocol();
|
virtual ~LinkProtocol();
|
||||||
|
|
||||||
status_t StartMonitoring(const char* deviceName);
|
status_t StartMonitoring(const char* deviceName);
|
||||||
status_t StopMonitoring();
|
status_t StopMonitoring();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
status_t SocketStatus(bool peek) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SocketStatus() const;
|
status_t _Unregister();
|
||||||
status_t _Unregister();
|
|
||||||
|
|
||||||
static status_t _MonitorData(net_device_monitor* monitor,
|
static status_t _MonitorData(net_device_monitor* monitor,
|
||||||
net_buffer* buffer);
|
net_buffer* buffer);
|
||||||
static void _MonitorEvent(net_device_monitor* monitor, int32 event);
|
static void _MonitorEvent(net_device_monitor* monitor,
|
||||||
|
int32 event);
|
||||||
|
|
||||||
net_device_monitor fMonitor;
|
private:
|
||||||
net_device_interface* fMonitoredDevice;
|
net_device_monitor fMonitor;
|
||||||
|
net_device_interface* fMonitoredDevice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -115,13 +119,15 @@ LinkProtocol::StopMonitoring()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
LinkProtocol::_SocketStatus() const
|
LinkProtocol::SocketStatus(bool peek) const
|
||||||
{
|
{
|
||||||
if (fMonitoredDevice == NULL)
|
if (fMonitoredDevice == NULL)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
return LocalDatagramSocket::_SocketStatus();
|
|
||||||
|
return LocalDatagramSocket::SocketStatus(peek);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
LinkProtocol::_Unregister()
|
LinkProtocol::_Unregister()
|
||||||
{
|
{
|
||||||
@@ -153,7 +159,7 @@ LinkProtocol::_MonitorEvent(net_device_monitor* monitor, int32 event)
|
|||||||
MutexLocker _(protocol->fLock);
|
MutexLocker _(protocol->fLock);
|
||||||
|
|
||||||
protocol->_Unregister();
|
protocol->_Unregister();
|
||||||
if (protocol->_IsEmpty()) {
|
if (protocol->IsEmpty()) {
|
||||||
protocol->WakeAll();
|
protocol->WakeAll();
|
||||||
notify_socket(protocol->socket, B_SELECT_READ, ENODEV);
|
notify_socket(protocol->socket, B_SELECT_READ, ENODEV);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user