* 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:
Axel Dörfler
2010-07-23 10:12:06 +00:00
parent b0e48987f0
commit d62ee168ed
2 changed files with 59 additions and 32 deletions
+39 -18
View File
@@ -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);
}
} }
+20 -14
View File
@@ -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);
} }