summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2010-11-25 17:43:51 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2010-11-25 17:43:51 +0100
commit44300ddcb2904105e2ecd56479bf396399dcab26 (patch)
treed8a1eef882e4edd784de0a41383d4c43c5b24fd6 /runtime
parentbd157a7d698f420ea3a9459fc90dd930c54a5e54 (diff)
parenta3c81f500a4d952ce93162a730cadee8fbc8116b (diff)
downloadrsyslog-44300ddcb2904105e2ecd56479bf396399dcab26.tar.gz
rsyslog-44300ddcb2904105e2ecd56479bf396399dcab26.tar.xz
rsyslog-44300ddcb2904105e2ecd56479bf396399dcab26.zip
Merge branch 'v5-beta' into v5-devel
Conflicts: ChangeLog configure.ac doc/imfile.html plugins/imfile/imfile.c runtime/rsyslog.h
Diffstat (limited to 'runtime')
-rw-r--r--runtime/Makefile.am1
-rw-r--r--runtime/atomic.h45
-rw-r--r--runtime/msg.c2
-rw-r--r--runtime/msg.h2
-rw-r--r--runtime/nsdpoll_ptcp.c1
-rw-r--r--runtime/nsdsel_gtls.c17
-rw-r--r--runtime/rsyslog.h124
-rw-r--r--runtime/typedefs.h148
-rw-r--r--runtime/unlimited_select.h1
9 files changed, 212 insertions, 129 deletions
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index 93817e75..09cb6b41 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -7,6 +7,7 @@ pkglib_LTLIBRARIES =
librsyslog_la_SOURCES = \
rsyslog.c \
rsyslog.h \
+ typedefs.h \
unicode-helper.h \
atomic.h \
batch.h \
diff --git a/runtime/atomic.h b/runtime/atomic.h
index da544c4b..790cb1c6 100644
--- a/runtime/atomic.h
+++ b/runtime/atomic.h
@@ -33,6 +33,8 @@
*/
#ifndef INCLUDED_ATOMIC_H
#define INCLUDED_ATOMIC_H
+#include <time.h>
+#include "typedefs.h"
/* for this release, we disable atomic calls because there seem to be some
* portability problems and we can not fix that without destabilizing the build.
@@ -42,7 +44,9 @@
# define ATOMIC_SUB(data, val, phlpmut) __sync_fetch_and_sub(data, val)
# define ATOMIC_ADD(data, val) __sync_fetch_and_add(&(data), val)
# define ATOMIC_INC(data, phlpmut) ((void) __sync_fetch_and_add(data, 1))
-# define ATOMIC_INC_AND_FETCH(data, phlpmut) __sync_fetch_and_add(data, 1)
+# define ATOMIC_INC_AND_FETCH_int(data, phlpmut) __sync_fetch_and_add(data, 1)
+# define ATOMIC_INC_AND_FETCH_unsigned(data, phlpmut) __sync_fetch_and_add(data, 1)
+# define ATOMIC_INC_AND_FETCH_uint64(data, phlpmut) __sync_fetch_and_add(data, 1)
# define ATOMIC_DEC(data, phlpmut) ((void) __sync_sub_and_fetch(data, 1))
# define ATOMIC_DEC_AND_FETCH(data, phlpmut) __sync_sub_and_fetch(data, 1)
# define ATOMIC_FETCH_32BIT(data, phlpmut) ((unsigned) __sync_fetch_and_and(data, 0xffffffff))
@@ -51,6 +55,7 @@
# define ATOMIC_STORE_1_TO_INT(data, phlpmut) __sync_fetch_and_or(data, 1)
# define ATOMIC_STORE_INT_TO_INT(data, val) __sync_fetch_and_or(&(data), (val))
# define ATOMIC_CAS(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal))
+# define ATOMIC_CAS_time_t(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal))
# define ATOMIC_CAS_VAL(data, oldVal, newVal, phlpmut) __sync_val_compare_and_swap(data, (oldVal), (newVal));
/* functions below are not needed if we have atomics */
@@ -104,6 +109,20 @@
return(bSuccess);
}
+ static inline int
+ ATOMIC_CAS_time_t(time_t *data, time_t oldVal, time_t newVal, pthread_mutex_t *phlpmut) {
+ int bSuccess;
+ pthread_mutex_lock(phlpmut);
+ if(*data == oldVal) {
+ *data = newVal;
+ bSuccess = 1;
+ } else {
+ bSuccess = 0;
+ }
+ pthread_mutex_unlock(phlpmut);
+ return(bSuccess);
+ }
+
static inline int
ATOMIC_CAS_VAL(int *data, int oldVal, int newVal, pthread_mutex_t *phlpmut) {
@@ -124,7 +143,7 @@
}
static inline int
- ATOMIC_INC_AND_FETCH(int *data, pthread_mutex_t *phlpmut) {
+ ATOMIC_INC_AND_FETCH_int(int *data, pthread_mutex_t *phlpmut) {
int val;
pthread_mutex_lock(phlpmut);
val = ++(*data);
@@ -132,6 +151,24 @@
return(val);
}
+ static inline unsigned
+ ATOMIC_INC_AND_FETCH_unsigned(unsigned *data, pthread_mutex_t *phlpmut) {
+ unsigned val;
+ pthread_mutex_lock(phlpmut);
+ val = ++(*data);
+ pthread_mutex_unlock(phlpmut);
+ return(val);
+ }
+
+ static inline unsigned
+ ATOMIC_INC_AND_FETCH_uint64(uint64 *data, pthread_mutex_t *phlpmut) {
+ uint64 val;
+ pthread_mutex_lock(phlpmut);
+ val = ++(*data);
+ pthread_mutex_unlock(phlpmut);
+ return(val);
+ }
+
static inline int
ATOMIC_DEC_AND_FETCH(int *data, pthread_mutex_t *phlpmut) {
int val;
@@ -158,7 +195,9 @@
}
#if 0
# warning "atomic builtins not available, using nul operations - rsyslogd will probably be racy!"
-# define ATOMIC_INC_AND_FETCH(data) (++(data))
+# define ATOMIC_INC_AND_FETCH_int(data) (++(data))
+# define ATOMIC_INC_AND_FETCH_unsigned(data) (++(data))
+# define ATOMIC_INC_AND_FETCH_uint64(data) (++(data))
# define ATOMIC_STORE_1_TO_32BIT(data) (data) = 1 // TODO: del
#endif
# define DEF_ATOMIC_HELPER_MUT(x) pthread_mutex_t x
diff --git a/runtime/msg.c b/runtime/msg.c
index f575b86b..82565f18 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -851,7 +851,7 @@ CODESTARTobjDestruct(msg)
* that we trim too often when the counter wraps.
*/
static unsigned iTrimCtr = 1;
- currCnt = ATOMIC_INC_AND_FETCH(&iTrimCtr, &mutTrimCtr);
+ currCnt = ATOMIC_INC_AND_FETCH_unsigned(&iTrimCtr, &mutTrimCtr);
if(currCnt % 100000 == 0) {
malloc_trim(128*1024);
}
diff --git a/runtime/msg.h b/runtime/msg.h
index d42f1de2..4897959c 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -60,8 +60,8 @@ struct msg {
flowControl_t flowCtlType; /**< type of flow control we can apply, for enqueueing, needs not to be persisted because
once data has entered the queue, this property is no longer needed. */
pthread_mutex_t mut;
+ int iRefCount; /* reference counter (0 = unused) */
sbool bDoLock; /* use the mutex? */
- short iRefCount; /* reference counter (0 = unused) */
short iSeverity; /* the severity 0..7 */
short iFacility; /* Facility code 0 .. 23*/
short offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */
diff --git a/runtime/nsdpoll_ptcp.c b/runtime/nsdpoll_ptcp.c
index 51006707..bc374c60 100644
--- a/runtime/nsdpoll_ptcp.c
+++ b/runtime/nsdpoll_ptcp.c
@@ -42,7 +42,6 @@
#include "nspoll.h"
#include "nsd_ptcp.h"
#include "nsdpoll_ptcp.h"
-#include "unlimited_select.h"
/* static data */
DEFobjStaticHelpers
diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c
index c3a93bee..1a389a00 100644
--- a/runtime/nsdsel_gtls.c
+++ b/runtime/nsdsel_gtls.c
@@ -76,6 +76,9 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
if(pNsdGTLS->iMode == 1) {
if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
++pThis->iBufferRcvReady;
+ dbgprintf("nsdsel_gtls: data already present in buffer, initiating "
+ "dummy select %p->iBufferRcvReady=%d\n",
+ pThis, pThis->iBufferRcvReady);
FINALIZE;
}
if(pNsdGTLS->rtryCall != gtlsRtry_None) {
@@ -109,6 +112,7 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
if(pThis->iBufferRcvReady > 0) {
/* we still have data ready! */
*piNumReady = pThis->iBufferRcvReady;
+ dbgprintf("nsdsel_gtls: doing dummy select, data present\n");
} else {
iRet = nsdsel_ptcp.Select(pThis->pTcp, piNumReady);
}
@@ -190,6 +194,9 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
if(pNsdGTLS->iMode == 1) {
if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) {
*pbIsReady = 1;
+ --pThis->iBufferRcvReady; /* one "pseudo-read" less */
+ dbgprintf("nsdl_gtls: dummy read, decermenting %p->iBufRcvReady, now %d\n",
+ pThis, pThis->iBufferRcvReady);
FINALIZE;
}
if(pNsdGTLS->rtryCall != gtlsRtry_None) {
@@ -200,6 +207,16 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
*pbIsReady = 0;
FINALIZE;
}
+ /* now we must ensure that we do not fall back to PTCP if we have
+ * done a "dummy" select. In that case, we know when the predicate
+ * is not matched here, we do not have data available for this
+ * socket. -- rgerhards, 2010-11-20
+ */
+ if(pThis->iBufferRcvReady) {
+ dbgprintf("nsd_gtls: dummy read, buffer not available for this FD\n");
+ *pbIsReady = 0;
+ FINALIZE;
+ }
}
CHKiRet(nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady));
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 7ccc9cb8..b47ef82e 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -25,6 +25,7 @@
*/
#ifndef INCLUDED_RSYSLOG_H
#define INCLUDED_RSYSLOG_H
+#include "typedefs.h"
/* ############################################################# *
* # Some constant values # *
@@ -94,129 +95,6 @@
#define CORE_FEATURE_BATCHING 1
/*#define CORE_FEATURE_whatever 2 ... and so on ... */
-/* under Solaris (actually only SPARC), we need to redefine some types
- * to be void, so that we get void* pointers. Otherwise, we will see
- * alignment errors.
- */
-/* some universal fixed size integer defines ... */
-typedef long long int64;
-typedef long long unsigned uint64;
-typedef int64 number_t; /* type to use for numbers - TODO: maybe an autoconf option? */
-typedef char intTiny; /* 0..127! */
-typedef unsigned char uintTiny; /* 0..255! */
-
-/* define some base data types */
-
-typedef unsigned char uchar;/* get rid of the unhandy "unsigned char" */
-typedef struct aUsrp_s aUsrp_t;
-typedef struct thrdInfo thrdInfo_t;
-typedef struct obj_s obj_t;
-typedef struct ruleset_s ruleset_t;
-typedef struct rule_s rule_t;
-//typedef struct filed selector_t;/* TODO: this so far resides in syslogd.c, think about modularization */
-typedef struct NetAddr netAddr_t;
-typedef struct netstrms_s netstrms_t;
-typedef struct netstrm_s netstrm_t;
-typedef struct nssel_s nssel_t;
-typedef struct nspoll_s nspoll_t;
-typedef enum nsdsel_waitOp_e nsdsel_waitOp_t;
-typedef struct nsd_ptcp_s nsd_ptcp_t;
-typedef struct nsd_gtls_s nsd_gtls_t;
-typedef struct nsd_gsspi_s nsd_gsspi_t;
-typedef struct nsd_nss_s nsd_nss_t;
-typedef struct nsdsel_ptcp_s nsdsel_ptcp_t;
-typedef struct nsdsel_gtls_s nsdsel_gtls_t;
-typedef struct nsdpoll_ptcp_s nsdpoll_ptcp_t;
-typedef struct wti_s wti_t;
-typedef struct msg msg_t;
-typedef struct queue_s qqueue_t;
-typedef struct prop_s prop_t;
-typedef struct interface_s interface_t;
-typedef struct objInfo_s objInfo_t;
-typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
-typedef rsRetVal (*errLogFunc_t)(uchar*); /* this is a trick to store a function ptr to a function returning a function ptr... */
-typedef struct permittedPeers_s permittedPeers_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */
-typedef struct permittedPeerWildcard_s permittedPeerWildcard_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */
-typedef struct tcpsrv_s tcpsrv_t;
-typedef struct tcps_sess_s tcps_sess_t;
-typedef struct strmsrv_s strmsrv_t;
-typedef struct strms_sess_s strms_sess_t;
-typedef struct vmstk_s vmstk_t;
-typedef struct batch_obj_s batch_obj_t;
-typedef struct batch_s batch_t;
-typedef struct wtp_s wtp_t;
-typedef struct modInfo_s modInfo_t;
-typedef struct parser_s parser_t;
-typedef struct parserList_s parserList_t;
-typedef struct strgen_s strgen_t;
-typedef struct strgenList_s strgenList_t;
-typedef struct statsobj_s statsobj_t;
-typedef struct statsctr_s statsctr_t;
-typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */
-typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */
-
-typedef struct tcpLstnPortList_s tcpLstnPortList_t; // TODO: rename?
-typedef struct strmLstnPortList_s strmLstnPortList_t; // TODO: rename?
-
-/* under Solaris (actually only SPARC), we need to redefine some types
- * to be void, so that we get void* pointers. Otherwise, we will see
- * alignment errors.
- */
-#ifdef OS_SOLARIS
- typedef void * obj_t_ptr;
- typedef void nsd_t;
- typedef void nsdsel_t;
- typedef void nsdpoll_t;
-#else
- typedef obj_t *obj_t_ptr;
- typedef obj_t nsd_t;
- typedef obj_t nsdsel_t;
- typedef obj_t nsdpoll_t;
-#endif
-
-
-#ifdef __hpux
-typedef unsigned int u_int32_t; /* TODO: is this correct? */
-typedef int socklen_t;
-#endif
-
-typedef struct epoll_event epoll_event_t;
-
-typedef char sbool; /* (small bool) I intentionally use char, to keep it slim so that many fit into the CPU cache! */
-
-/* settings for flow control
- * TODO: is there a better place for them? -- rgerhards, 2008-03-14
- */
-typedef enum {
- eFLOWCTL_NO_DELAY = 0, /**< UDP and other non-delayable sources */
- eFLOWCTL_LIGHT_DELAY = 1, /**< some light delay possible, but no extended period of time */
- eFLOWCTL_FULL_DELAY = 2 /**< delay possible for extended period of time */
-} flowControl_t;
-
-/* filter operations */
-typedef enum {
- FIOP_NOP = 0, /* do not use - No Operation */
- FIOP_CONTAINS = 1, /* contains string? */
- FIOP_ISEQUAL = 2, /* is (exactly) equal? */
- FIOP_STARTSWITH = 3, /* starts with a string? */
- FIOP_REGEX = 4, /* matches a (BRE) regular expression? */
- FIOP_EREREGEX = 5 /* matches a ERE regular expression? */
-} fiop_t;
-
-
-/* multi-submit support.
- * This is done via a simple data structure, which holds the number of elements
- * as well as an array of to-be-submitted messages.
- * rgerhards, 2009-06-16
- */
-typedef struct multi_submit_s multi_submit_t;
-struct multi_submit_s {
- short maxElem; /* maximum number of Elements */
- short nElem; /* current number of Elements, points to the next one FREE */
- msg_t **ppMsgs;
-};
-
-
#ifndef _PATH_CONSOLE
#define _PATH_CONSOLE "/dev/console"
#endif
diff --git a/runtime/typedefs.h b/runtime/typedefs.h
new file mode 100644
index 00000000..d3da7699
--- /dev/null
+++ b/runtime/typedefs.h
@@ -0,0 +1,148 @@
+/* This defines some types commonly used. Do NOT include any other
+ * rsyslog runtime file.
+ *
+ * Begun 2010-11-25 RGerhards
+ *
+ * Copyright (C) 2005-2008 by Rainer Gerhards and Adiscon GmbH
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * The rsyslog runtime library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The rsyslog runtime library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
+ */
+#ifndef INCLUDED_TYPEDEFS_H
+#define INCLUDED_TYPEDEFS_H
+
+/* some universal fixed size integer defines ... */
+typedef long long int64;
+typedef long long unsigned uint64;
+typedef int64 number_t; /* type to use for numbers - TODO: maybe an autoconf option? */
+typedef char intTiny; /* 0..127! */
+typedef unsigned char uintTiny; /* 0..255! */
+
+/* define some base data types */
+
+typedef unsigned char uchar;/* get rid of the unhandy "unsigned char" */
+typedef struct aUsrp_s aUsrp_t;
+typedef struct thrdInfo thrdInfo_t;
+typedef struct obj_s obj_t;
+typedef struct ruleset_s ruleset_t;
+typedef struct rule_s rule_t;
+//typedef struct filed selector_t;/* TODO: this so far resides in syslogd.c, think about modularization */
+typedef struct NetAddr netAddr_t;
+typedef struct netstrms_s netstrms_t;
+typedef struct netstrm_s netstrm_t;
+typedef struct nssel_s nssel_t;
+typedef struct nspoll_s nspoll_t;
+typedef enum nsdsel_waitOp_e nsdsel_waitOp_t;
+typedef struct nsd_ptcp_s nsd_ptcp_t;
+typedef struct nsd_gtls_s nsd_gtls_t;
+typedef struct nsd_gsspi_s nsd_gsspi_t;
+typedef struct nsd_nss_s nsd_nss_t;
+typedef struct nsdsel_ptcp_s nsdsel_ptcp_t;
+typedef struct nsdsel_gtls_s nsdsel_gtls_t;
+typedef struct nsdpoll_ptcp_s nsdpoll_ptcp_t;
+typedef struct wti_s wti_t;
+typedef struct msg msg_t;
+typedef struct queue_s qqueue_t;
+typedef struct prop_s prop_t;
+typedef struct interface_s interface_t;
+typedef struct objInfo_s objInfo_t;
+typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
+typedef rsRetVal (*errLogFunc_t)(uchar*); /* this is a trick to store a function ptr to a function returning a function ptr... */
+typedef struct permittedPeers_s permittedPeers_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */
+typedef struct permittedPeerWildcard_s permittedPeerWildcard_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */
+typedef struct tcpsrv_s tcpsrv_t;
+typedef struct tcps_sess_s tcps_sess_t;
+typedef struct strmsrv_s strmsrv_t;
+typedef struct strms_sess_s strms_sess_t;
+typedef struct vmstk_s vmstk_t;
+typedef struct batch_obj_s batch_obj_t;
+typedef struct batch_s batch_t;
+typedef struct wtp_s wtp_t;
+typedef struct modInfo_s modInfo_t;
+typedef struct parser_s parser_t;
+typedef struct parserList_s parserList_t;
+typedef struct strgen_s strgen_t;
+typedef struct strgenList_s strgenList_t;
+typedef struct statsobj_s statsobj_t;
+typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */
+typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */
+
+typedef struct tcpLstnPortList_s tcpLstnPortList_t; // TODO: rename?
+typedef struct strmLstnPortList_s strmLstnPortList_t; // TODO: rename?
+
+/* under Solaris (actually only SPARC), we need to redefine some types
+ * to be void, so that we get void* pointers. Otherwise, we will see
+ * alignment errors.
+ */
+#ifdef OS_SOLARIS
+ typedef void * obj_t_ptr;
+ typedef void nsd_t;
+ typedef void nsdsel_t;
+ typedef void nsdpoll_t;
+#else
+ typedef obj_t *obj_t_ptr;
+ typedef obj_t nsd_t;
+ typedef obj_t nsdsel_t;
+ typedef obj_t nsdpoll_t;
+#endif
+
+
+#ifdef __hpux
+typedef unsigned int u_int32_t; /* TODO: is this correct? */
+typedef int socklen_t;
+#endif
+
+typedef struct epoll_event epoll_event_t;
+
+typedef char sbool; /* (small bool) I intentionally use char, to keep it slim so that many fit into the CPU cache! */
+
+/* settings for flow control
+ * TODO: is there a better place for them? -- rgerhards, 2008-03-14
+ */
+typedef enum {
+ eFLOWCTL_NO_DELAY = 0, /**< UDP and other non-delayable sources */
+ eFLOWCTL_LIGHT_DELAY = 1, /**< some light delay possible, but no extended period of time */
+ eFLOWCTL_FULL_DELAY = 2 /**< delay possible for extended period of time */
+} flowControl_t;
+
+/* filter operations */
+typedef enum {
+ FIOP_NOP = 0, /* do not use - No Operation */
+ FIOP_CONTAINS = 1, /* contains string? */
+ FIOP_ISEQUAL = 2, /* is (exactly) equal? */
+ FIOP_STARTSWITH = 3, /* starts with a string? */
+ FIOP_REGEX = 4, /* matches a (BRE) regular expression? */
+ FIOP_EREREGEX = 5 /* matches a ERE regular expression? */
+} fiop_t;
+
+
+/* multi-submit support.
+ * This is done via a simple data structure, which holds the number of elements
+ * as well as an array of to-be-submitted messages.
+ * rgerhards, 2009-06-16
+ */
+typedef struct multi_submit_s multi_submit_t;
+struct multi_submit_s {
+ short maxElem; /* maximum number of Elements */
+ short nElem; /* current number of Elements, points to the next one FREE */
+ msg_t **ppMsgs;
+};
+
+#endif /* multi-include protection */
+/* vim:set ai:
+ */
diff --git a/runtime/unlimited_select.h b/runtime/unlimited_select.h
index 32dadc03..3fa7eb06 100644
--- a/runtime/unlimited_select.h
+++ b/runtime/unlimited_select.h
@@ -23,6 +23,7 @@
*/
#ifndef UNLIMITED_SELECT_H_INCLUDED
+#define UNLIMITED_SELECT_H_INCLUDED
#include <string.h>
#include <stdlib.h>