File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / msg.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:32:47 2012 UTC (12 years, 4 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_6, HEAD
mpd

    1: 
    2: /*
    3:  * msg.c
    4:  *
    5:  * Written by Archie Cobbs <archie@freebsd.org>
    6:  * Copyright (c) 1995-1999 Whistle Communications, Inc. All rights reserved.
    7:  * See ``COPYRIGHT.whistle''
    8:  */
    9: 
   10: #include "ppp.h"
   11: #include "msg.h"
   12: 
   13: /*
   14:  * DEFINITIONS
   15:  */
   16: 
   17: /* Which pipe file descriptor is which */
   18: 
   19:   #define PIPE_READ		0
   20:   #define PIPE_WRITE		1
   21: 
   22:   struct mpmsg
   23:   {
   24:     int		type;
   25:     void	(*func)(int type, void *arg);
   26:     void	*arg;
   27:     const char	*dbg;
   28:   };
   29:   typedef struct mpmsg	*Msg;
   30: 
   31:   #define	MSG_QUEUE_LEN	8192
   32:   #define	MSG_QUEUE_MASK	0x1FFF
   33: 
   34:   struct mpmsg	msgqueue[MSG_QUEUE_LEN];
   35:   int		msgqueueh = 0;
   36:   int		msgqueuet = 0;
   37:   #define	QUEUELEN()	((msgqueueh >= msgqueuet)?	\
   38: 	(msgqueueh - msgqueuet):(msgqueueh + MSG_QUEUE_LEN - msgqueuet))
   39: 
   40:   int           msgpipe[2];
   41:   int		msgpipesent = 0;
   42:   EventRef	msgevent;
   43: 
   44: /*
   45:  * INTERNAL FUNCTIONS
   46:  */
   47: 
   48:   static void	MsgEvent(int type, void *cookie);
   49: 
   50: /*
   51:  * MsgRegister()
   52:  */
   53: 
   54: void
   55: MsgRegister2(MsgHandler *m, void (*func)(int type, void *arg), const char *dbg)
   56: {
   57:     if ((msgpipe[0]==0) || (msgpipe[1]==0)) {
   58: 	if (pipe(msgpipe) < 0) {
   59: 	    Perror("%s: Can't create message pipe", 
   60: 		__FUNCTION__);
   61: 	    DoExit(EX_ERRDEAD);
   62: 	}
   63: 	fcntl(msgpipe[PIPE_READ], F_SETFD, 1);
   64: 	fcntl(msgpipe[PIPE_WRITE], F_SETFD, 1);
   65: 
   66: 	if (fcntl(msgpipe[PIPE_READ], F_SETFL, O_NONBLOCK) < 0)
   67:     	    Perror("%s: fcntl", __FUNCTION__);
   68: 	if (fcntl(msgpipe[PIPE_WRITE], F_SETFL, O_NONBLOCK) < 0)
   69:     	    Perror("%s: fcntl", __FUNCTION__);
   70: 
   71: 	if (EventRegister(&msgevent, EVENT_READ,
   72: 		msgpipe[PIPE_READ], EVENT_RECURRING, MsgEvent, NULL) < 0) {
   73: 	    Perror("%s: Can't register event", __FUNCTION__);
   74: 	    DoExit(EX_ERRDEAD);
   75:         }
   76:     }
   77: 
   78:     m->func = func;
   79:     m->dbg = dbg;
   80: }
   81: 
   82: /*
   83:  * MsgUnRegister()
   84:  */
   85: 
   86: void
   87: MsgUnRegister(MsgHandler *m)
   88: {
   89:     m->func = NULL;
   90:     m->dbg = NULL;
   91: }
   92: 
   93: /*
   94:  * MsgEvent()
   95:  */
   96: 
   97: static void
   98: MsgEvent(int type, void *cookie)
   99: {
  100:     char	buf[16];
  101:     /* flush signaling pipe */
  102:     msgpipesent = 0;
  103:     while (read(msgpipe[PIPE_READ], buf, sizeof(buf)) == sizeof(buf));
  104: 
  105:     while (msgqueuet != msgqueueh) {
  106: 	Log(LG_EVENTS, ("EVENT: Message %d to %s received",
  107: 	    msgqueue[msgqueuet].type, msgqueue[msgqueuet].dbg));
  108: 	(*(msgqueue[msgqueuet].func))(msgqueue[msgqueuet].type, msgqueue[msgqueuet].arg);
  109: 	Log(LG_EVENTS, ("EVENT: Message %d to %s processed",
  110: 	    msgqueue[msgqueuet].type, msgqueue[msgqueuet].dbg));
  111: 
  112: 	msgqueuet = (msgqueuet + 1) & MSG_QUEUE_MASK;
  113: 	SETOVERLOAD(QUEUELEN());
  114:     }
  115: }
  116: 
  117: /*
  118:  * MsgSend()
  119:  */
  120: 
  121: void
  122: MsgSend(MsgHandler *m, int type, void *arg)
  123: {
  124:     assert(m);
  125:     assert(m->func);
  126: 
  127:     msgqueue[msgqueueh].type = type;
  128:     msgqueue[msgqueueh].func = m->func;
  129:     msgqueue[msgqueueh].arg = arg;
  130:     msgqueue[msgqueueh].dbg = m->dbg;
  131: 
  132:     msgqueueh = (msgqueueh + 1) & MSG_QUEUE_MASK;
  133:     if (msgqueuet == msgqueueh) {
  134:         Log(LG_ERR, ("%s: Fatal message queue overflow!", __FUNCTION__));
  135:         DoExit(EX_ERRDEAD);
  136:     }
  137: 
  138:     SETOVERLOAD(QUEUELEN());
  139: 
  140:     if (!msgpipesent) {
  141: 	char	buf[1] = { 0x2a };
  142: 	if (write(msgpipe[PIPE_WRITE], buf, 1) > 0)
  143: 	    msgpipesent = 1;
  144:     }
  145:     Log(LG_EVENTS, ("EVENT: Message %d to %s sent", type, m->dbg));
  146: }
  147: 
  148: /*
  149:  * MsgName()
  150:  */
  151: 
  152: const char *
  153: MsgName(int msg)
  154: {
  155:   switch (msg)
  156:   {
  157:     case MSG_OPEN:
  158:       return("OPEN");
  159:     case MSG_CLOSE:
  160:       return("CLOSE");
  161:     case MSG_UP:
  162:       return("UP");
  163:     case MSG_DOWN:
  164:       return("DOWN");
  165:     case MSG_SHUTDOWN:
  166:       return("SHUTDOWN");
  167:     default:
  168:       return("???");
  169:   }
  170: }
  171: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>