Datagram::DgramPoll Class Reference

Datagram service provider using sockets and poll. More...

Inheritance diagram for Datagram::DgramPoll:
Datagram::Provider Poll::User

Public Member Functions

virtual void Die ()
 Make this provider go away.
 
void tidy ()
 Tidy up - close connections etc.
 
void actualDeliver (::Poll::pollmsg *msg)
 Actual Deliver events to Poll provider.
 
void actualDeliver (External *ext)
 Set external.
 
void actualDeliver (ListenRequest *req)
 listen
 
void actualDeliver (DataRequest *req)
 send data
 
void actualDeliver (ReadRequest *req)
 ReadRequest.
 
void actualDeliver (MulticastRequest *req)
 Multicast listen.
 
void actualDeliver (MulticastParams *req)
 Multicast sending control.
 
virtual void Deliver (::Poll::pollmsg *msg)
 Deliver events from Poll provider.
 
virtual void Deliver (External *ext)
 Set external.
 
virtual void Deliver (ListenRequest *req)
 listen
 
virtual void Deliver (DataRequest *req)
 send data
 
virtual void Deliver (ReadRequest *req)
 Read request.
 
virtual void Deliver (MulticastRequest *req)
 Multicast listening.
 
virtual void Deliver (MulticastParams *req)
 Set Multicast sending params.
 
virtual void Deliver (LengthFnxRequest *)
 Set length function.
 
- Public Member Functions inherited from Datagram::Provider
 Provider ()
 The user of this provider.
 
virtual ~Provider ()
 Destructor should be virtual.
 
void SetUser (User *u)
 set the user
 
UserGetUser ()
 get the user
 
- Public Member Functions inherited from Poll::User
 User ()
 User's view of events.
 
virtual ~User ()
 Destructor is virtual.
 
virtual void Deliver (pollmsg *msg)=0
 Deliver events to Poll user.
 
virtual void actualDeliver (pollmsg *msg)=0
 Deliver events to Poll user.
 

Additional Inherited Members

- Static Public Member Functions inherited from Datagram::Provider
static EVENTSVC_DLL ProviderProviderFactory (const char *type, MSGstruct *msp)
 Factory method for Stream provider.
 
- Data Fields inherited from Poll::User
UserEvent _event
 
endpoint_t _fd
 Event to User.
 
unsigned _pevents
 FD for this user.
 
unsigned _uevents
 Provider's view of events.
 

Detailed Description

Datagram service provider using sockets and poll.

Definition at line 35 of file datagram_socket_poll.C.

Constructor & Destructor Documentation

◆ ~DgramPoll()

Datagram::DgramPoll::~DgramPoll ( )
inlineprotected

Definition at line 97 of file datagram_socket_poll.C.

97 {
98 tidy();
99 }
void tidy()
Tidy up - close connections etc.

◆ DgramPoll()

Datagram::DgramPoll::DgramPoll ( )
inline

Definition at line 102 of file datagram_socket_poll.C.

102 :
103 _poller (0)
104 { _rreq.len = 0; _wreq.len = 0; _event.Init (this); }
void Init(C *rcvr)
Set the target.
Definition Syncmsg.h:48
size_t len
Pointer to data to be transferred.
size_t len
Address of data.

Member Function Documentation

◆ Die()

virtual void Datagram::DgramPoll::Die ( )
inlinevirtual

Make this provider go away.

Implements Datagram::Provider.

Definition at line 107 of file datagram_socket_poll.C.

107{ delete this; }

◆ tidy()

void Datagram::DgramPoll::tidy ( )
inline

Tidy up - close connections etc.

Definition at line 110 of file datagram_socket_poll.C.

110 {
111 SetUser (0);
112
113 if ( _fd != INVALID_ENDPOINT ) {
114
115 if ( _poller != 0 ) {
116 _poller->Deregister (this);
117 _poller = 0;
118 }
119
120 closesocket (_fd);
121 _fd = INVALID_ENDPOINT;
122
123 _event.Cancel ();
124 }
125
126 _rreq.len = _wreq.len = 0;
127 }
void SetUser(User *u)
set the user
virtual void Deregister(User *user)=0
Deregister endpoint.
endpoint_t _fd
Event to User.

References Poll::User::_fd, Poll::Provider::Deregister(), Datagram::ReadRequest::len, Datagram::DataRequest::len, and Datagram::Provider::SetUser().

◆ actualDeliver() [1/7]

void DgramPoll::actualDeliver ( ::Poll::pollmsg msg)

Actual Deliver events to Poll provider.

Definition at line 412 of file datagram_socket_poll.C.

413{
414 if ( checkUser() ) return;
415
416 StatusIndication statusind;
417
418 LOG_DEBUG (("DgramPoll::actualDeliver (pollmsg = %x)", msg->events));
419
420 // Poller no longer listening
421 _pevents = 0;
422
423 if ( (msg->events & ::Poll::Event_Terminate) ) {
424 // System terminating
425 _uevents = 0;
426
427 // Tell User
428 MSG_IOevent_Terminating_SET (&statusind.msg);
429 sendStatus (&statusind);
430
431 // Close first, otherwise calls back to poller
432 closesocket (_fd);
433 _fd = INVALID_ENDPOINT;
434 _poller = 0;
435
436 tidy ();
437
438 return;
439 }
440
441 if ( msg->events &
442 (::Poll::Event_Err | ::Poll::Event_Hup | ::Poll::Event_Nval) ) {
443
444 // Don't want any events
445 _uevents = 0;
446
447 // Get error from socket
448 int eno;
449#ifdef GETSOCKOPT_NEEDS_INTP
450 int olen;
451#else
452 socklen_t olen;
453#endif
454 olen = sizeof eno;
455 int rc = getsockopt (_fd, SOL_SOCKET, SO_ERROR, (char *)&eno, &olen);
456
457 const char *argv[1];
458 argv[0] = "poll";
459
460 MSGsetv (&statusind.msg, MSG_IOevent_IOerror, 1, argv);
461
462 if ( rc == 0 ) {
463 MSGstruct sockerr;
464 MSGsetv (&sockerr,
465 MSGID_BUILD(MSGLEVEL_ERROR, MSGID_SYSFAC, eno),
466 0, 0);
467 MSGappend (&statusind.msg, &sockerr);
468 } else {
469 MSGappendsyserror (&statusind.msg);
470 }
471
472 sendStatus (&statusind);
473
474 tidy ();
475
476 return;
477 }
478
479 // Cancel desired events
480 _uevents &= ~msg->events;
481
482 if ( msg->events & ::Poll::Event_In ) {
483 if ( _rreq.len != 0 ) {
484 // Stuff to read. If does not complete, then wait again
485 if ( !doRead () )
486 waitEvent (::Poll::Event_In);
487 }
488 }
489
490 if ( msg->events & ::Poll::Event_Out ) {
491 if ( _wreq.len != 0 ) {
492 // Stuff to write. If does not complete, then wait again
493 if ( !doWrite () )
494 waitEvent (::Poll::Event_Out);
495 }
496 }
497
498 if ( (_uevents & ~_pevents) && _poller )
499 _poller->Control (this);
500}
virtual void Control(User *user)=0
Set the events which are interesting for end point.
unsigned _pevents
FD for this user.
unsigned _uevents
Provider's view of events.

References Datagram::StatusIndication::msg.

Referenced by Deliver(), Deliver(), Deliver(), Deliver(), Deliver(), Deliver(), and Deliver().

◆ actualDeliver() [2/7]

void DgramPoll::actualDeliver ( Datagram::External ext)

Set external.

Definition at line 502 of file datagram_socket_poll.C.

503{
504 if ( checkUser() ) return;
505
506 StatusIndication statusind;
507
508 LOG_DEBUG (("DgramPoll::actualDeliver (External)"));
509
510 if ( _fd == INVALID_ENDPOINT ) {
511 MSG_IOevent_NotConnected_SET (&statusind.msg);
512 sendStatus (&statusind);
513 return;
514 }
515
516 _fd = ext->fd;
517}

References Datagram::StatusIndication::msg.

◆ actualDeliver() [3/7]

void DgramPoll::actualDeliver ( Datagram::ListenRequest req)

listen

Definition at line 519 of file datagram_socket_poll.C.

520{
521 if ( checkUser() ) return;
522
523 StatusIndication statusind;
524
525 LOG_DEBUG (("DgramPoll::actualDeliver (ListenRequest)"));
526
527 if ( !req->laddr ) {
528 // Stopping the listen
529 tidy();
530 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
531 sendStatus (&statusind);
532 return;
533
534 } else if ( _fd != INVALID_ENDPOINT ) {
535 MSG_IOevent_NotConnected_SET (&statusind.msg);
536
537 sendStatus (&statusind);
538
539 return;
540 }
541
542 int family;
543
544 switch ( req->laddr->sa_family ) {
545#ifdef AF_UNIX
546 case AF_UNIX:
547 family = PF_UNIX;
548 break;
549#endif
550
551 case AF_INET:
552 family = PF_INET;
553 break;
554
555#if defined(AF_INET6) && defined(PF_INET6)
556 case AF_INET6:
557 family = PF_INET6;
558 break;
559#endif
560
561 default:
562 MSG_IOevent_AddrType_SET (&statusind.msg, req->laddr->sa_family);
563 sendStatus (&statusind);
564 return;
565 }
566
567 int fd = socket (family, SOCK_DGRAM, 0);
568
569 if ( fd < 0 ) {
570 MSG_IOevent_IOerror_SET (&statusind.msg, "socket");
571 sendStatus (&statusind);
572 return;
573 }
574
575 if ( bind (fd, req->laddr, req->lalen ) != 0 ) {
576 MSG_IOevent_IOerror_SET (&statusind.msg, "bind");
577 sendStatus (&statusind);
578 closesocket (fd);
579 return;
580 }
581
582#ifdef FD_CLOEXEC
583 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
584#endif
585
586#ifdef O_NONBLOCK
587 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
588 MSG_IOevent_IOerror_SET (&statusind.msg, "fcntl");
589 sendStatus (&statusind);
590 closesocket (fd);
591 return;
592 }
593#elif defined (FIONBIO)
594 char onoff = 1;
595 if ( ioctl (fd, FIONBIO, &onoff) != 0 ) {
596 MSG_IOevent_IOerror_SET (&statusind.msg, "ioctl");
597 sendStatus (&statusind);
598 closesocket (fd);
599 return;
600 }
601#else
602# error Cannot set socket into non-blocking more
603#endif
604
605
606 _fd = fd;
607}
socklen_t lalen
Listen address.

References Datagram::ListenRequest::lalen, and Datagram::StatusIndication::msg.

◆ actualDeliver() [4/7]

void DgramPoll::actualDeliver ( Datagram::DataRequest req)

send data

Definition at line 609 of file datagram_socket_poll.C.

610{
611 if ( checkUser() ) return;
612
613 StatusIndication statusind;
614
615 LOG_DEBUG (("DgramPoll::actualDeliver (DataRequest)"));
616
617 if ( _fd == INVALID_ENDPOINT ) {
618 MSG_IOevent_NotConnected_SET (&statusind.msg);
619 sendStatus (&statusind);
620 return;
621 }
622
623 // Note: should not attempt to write zero bytes
624 if ( req->buf == 0 || req->len == 0 ) {
625 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
626 req->buf == NULL ?
627 "buffer pointer" :
628 "zero length");
629
630 sendStatus (&statusind);
631
632 return;
633 }
634
635 if ( _wreq.len != 0 ) {
636 ReleaseBuf release;
637
638 release.provider = this;
639 release.buf = req->buf;
640 release.len = -1;
641
642 GetUser()->Deliver (&release);
643
644 MSG_IOevent_DupWrite_SET (&statusind.msg);
645
646 sendStatus (&statusind);
647
648 return;
649 }
650
651 _wreq = *req;
652
653 if ( !doWrite () ) {
654 // Write blocked, tell poller we want to know when can write
655 waitEvent (::Poll::Event_Out);
656 }
657}
User * GetUser()
get the user
virtual void Deliver(DataIndication *data)=0
Receive data read by provider.

References Datagram::ReleaseBuf::buf, Datagram::DataRequest::len, Datagram::ReleaseBuf::len, and Datagram::StatusIndication::msg.

◆ actualDeliver() [5/7]

void DgramPoll::actualDeliver ( Datagram::ReadRequest req)

ReadRequest.

Definition at line 659 of file datagram_socket_poll.C.

660{
661 if ( checkUser() ) return;
662
663 DataIndication dataind;
664 StatusIndication statusind;
665
666 LOG_DEBUG (("DgramPoll::actualDeliver (ReadRequest)"));
667
668 if ( _fd == INVALID_ENDPOINT ) {
669 MSG_IOevent_NotConnected_SET (&statusind.msg);
670 sendStatus (&statusind);
671 return;
672 }
673
674 if ( req->buf == 0 || req->len == 0 ) {
675 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
676 req->buf == NULL ?
677 "buffer pointer" :
678 "zero length");
679
680 sendStatus (&statusind);
681
682 return;
683 }
684
685 if ( _rreq.len != 0 ) {
686 dataind.provider = this;
687 dataind.buf = req->buf;
688 dataind.len = -1;
689 dataind.arq = false;
690
691 GetUser()->Deliver (&dataind);
692
693 MSG_IOevent_DupRead_SET (&statusind.msg);
694
695 sendStatus (&statusind);
696
697 return;
698 }
699
700 _rreq = *req;
701
702 // Attempt read first, to avoid waking poll if possible
703 if ( doRead () )
704 return;
705
706 // tell poller we are interested in read events
707 waitEvent (::Poll::Event_In);
708}

References Datagram::DataIndication::arq, Datagram::DataIndication::buf, Datagram::ReadRequest::len, Datagram::DataIndication::len, and Datagram::StatusIndication::msg.

◆ actualDeliver() [6/7]

void DgramPoll::actualDeliver ( Datagram::MulticastRequest req)

Multicast listen.

Definition at line 756 of file datagram_socket_poll.C.

757{
758 if ( checkUser() ) return;
759
760 LOG_DEBUG (("DgramPoll::actualDeliver (MulticastRequest)"));
761
762 StatusIndication statusind;
763
764 if ( _fd == INVALID_ENDPOINT ) {
765 MSG_IOevent_NotConnected_SET (&statusind.msg);
766 sendStatus (&statusind);
767 return;
768 }
769
770 struct ip_mreq mreq;
771
772 mreq.imr_multiaddr = req->maddr;
773 mreq.imr_interface.s_addr = INADDR_ANY;
774
775 int rc = setsockopt (_fd, IPPROTO_IP,
776 req->listen ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP,
777 (char *)&mreq, sizeof mreq);
778
779 if ( rc != 0 ) {
780 MSG_IOevent_IOerror_SET (&statusind.msg, req->listen ?
781 "set add membership": "set drop membership");
782 sendStatus (&statusind);
783 tidy ();
784 }
785}
bool listen
The multicast address.

References Datagram::MulticastRequest::listen, and Datagram::StatusIndication::msg.

◆ actualDeliver() [7/7]

void DgramPoll::actualDeliver ( Datagram::MulticastParams req)

Multicast sending control.

Definition at line 710 of file datagram_socket_poll.C.

711{
712 if ( checkUser() ) return;
713
714 LOG_DEBUG (("DgramPoll::actualDeliver (MulticastParam)"));
715
716 StatusIndication statusind;
717
718 if ( _fd == INVALID_ENDPOINT ) {
719 MSG_IOevent_NotConnected_SET (&statusind.msg);
720 sendStatus (&statusind);
721 return;
722 }
723
724 int rc;
725
726 if ( req->ttl > 0 ) {
727 unsigned char ttl = req->ttl;
728
729 rc = setsockopt (_fd, IPPROTO_IP,
730 IP_MULTICAST_TTL,
731 (char *)&ttl, sizeof ttl);
732
733 if ( rc != 0 ) {
734 MSG_IOevent_IOerror_SET (&statusind.msg, "set multicast ttl");
735 sendStatus (&statusind);
736 tidy ();
737 }
738 }
739
740 if ( req->loop >= 0 ) {
741 int onoff = req->loop > 0 ? 1 : 0;
742
743 rc = setsockopt (_fd, IPPROTO_IP,
744 IP_MULTICAST_LOOP,
745 (char *)&onoff, sizeof onoff);
746
747 if ( rc != 0 ) {
748 MSG_IOevent_IOerror_SET (&statusind.msg, "set multicast loop");
749 sendStatus (&statusind);
750 tidy ();
751 }
752 }
753}
int loop
Set the ttl for multicast, 0: no change.

References Datagram::MulticastParams::loop, and Datagram::StatusIndication::msg.

◆ Deliver() [1/8]

virtual void Datagram::DgramPoll::Deliver ( ::Poll::pollmsg msg)
inlinevirtual

Deliver events from Poll provider.

Definition at line 157 of file datagram_socket_poll.C.

157 {
158 actualDeliver (msg);
159 }
void actualDeliver(::Poll::pollmsg *msg)
Actual Deliver events to Poll provider.

References actualDeliver().

◆ Deliver() [2/8]

virtual void Datagram::DgramPoll::Deliver ( External ext)
inlinevirtual

Set external.

Implements Datagram::Provider.

Definition at line 163 of file datagram_socket_poll.C.

163 {
164 actualDeliver (ext);
165 }

References actualDeliver().

◆ Deliver() [3/8]

virtual void Datagram::DgramPoll::Deliver ( ListenRequest req)
inlinevirtual

listen

Implements Datagram::Provider.

Definition at line 168 of file datagram_socket_poll.C.

168 {
169 actualDeliver (req);
170 }

References actualDeliver().

◆ Deliver() [4/8]

virtual void Datagram::DgramPoll::Deliver ( DataRequest req)
inlinevirtual

send data

Implements Datagram::Provider.

Definition at line 173 of file datagram_socket_poll.C.

173 {
174 actualDeliver (req);
175 }

References actualDeliver().

◆ Deliver() [5/8]

virtual void Datagram::DgramPoll::Deliver ( ReadRequest req)
inlinevirtual

Read request.

Implements Datagram::Provider.

Definition at line 178 of file datagram_socket_poll.C.

178 {
179 actualDeliver (req);
180 }

References actualDeliver().

◆ Deliver() [6/8]

virtual void Datagram::DgramPoll::Deliver ( MulticastRequest req)
inlinevirtual

Multicast listening.

Implements Datagram::Provider.

Definition at line 183 of file datagram_socket_poll.C.

183 {
184 actualDeliver (req);
185 }

References actualDeliver().

◆ Deliver() [7/8]

virtual void Datagram::DgramPoll::Deliver ( MulticastParams req)
inlinevirtual

Set Multicast sending params.

Implements Datagram::Provider.

Definition at line 188 of file datagram_socket_poll.C.

188 {
189 actualDeliver (req);
190 }

References actualDeliver().

◆ Deliver() [8/8]

virtual void Datagram::DgramPoll::Deliver ( LengthFnxRequest )
inlinevirtual

Set length function.

Implements Datagram::Provider.

Definition at line 193 of file datagram_socket_poll.C.

193 {
194 // Don't bother to synchronize this
195 }

The documentation for this class was generated from the following file:

All rights reserved © 2002 - 2024 Isode Ltd.