0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <ndrx_config.h>
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <errno.h>
0041
0042 #include <ndrstandard.h>
0043 #include <ndebug.h>
0044 #include <utlist.h>
0045 #include <string.h>
0046 #include "srv_int.h"
0047 #include "tperror.h"
0048 #include <atmi_int.h>
0049 #include <atmi_shm.h>
0050
0051
0052
0053
0054
0055 pollextension_rec_t * ndrx_G_pollext=NULL;
0056 exprivate int M_pollsync = EXTRUE;
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 exprivate int ext_find_poller_cmp(pollextension_rec_t *a, pollextension_rec_t *b)
0068 {
0069 return (a->fd==b->fd?EXSUCCEED:EXFAIL);
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079 expublic void ndrx_ext_pollsync(int flag)
0080 {
0081 M_pollsync=flag;
0082 NDRX_LOG(log_info, "Extension poll sync flag set to: %d", M_pollsync);
0083 }
0084
0085
0086
0087
0088
0089
0090 expublic pollextension_rec_t * ext_find_poller(int fd)
0091 {
0092 pollextension_rec_t *ret=NULL, eltmp;
0093
0094 eltmp.fd = fd;
0095 DL_SEARCH(ndrx_G_pollext, ret, &eltmp, ext_find_poller_cmp);
0096
0097 return ret;
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107 expublic int _tpext_addpollerfd(int fd, uint32_t events,
0108 void *ptr1, int (*p_pollevent)(int fd, uint32_t events, void *ptr1))
0109 {
0110 int ret=EXSUCCEED;
0111 pollextension_rec_t * pollext = NULL;
0112 pollextension_rec_t * existing = NULL;
0113 struct ndrx_epoll_event ev;
0114
0115 if (NULL==G_server_conf.service_array && M_pollsync)
0116 {
0117 ndrx_TPset_error_fmt(TPEPROTO, "Cannot add custom poller at init stage!");
0118 ret=EXFAIL;
0119 goto out;
0120 }
0121
0122
0123 existing = ext_find_poller(fd);
0124 if (NULL!=existing)
0125 {
0126 ndrx_TPset_error_fmt(TPEMATCH, "Poller for fd %d already exists", fd);
0127 NDRX_LOG(log_error, "Poller for fd %d already exists!", fd);
0128 ret=EXFAIL;
0129 goto out;
0130 }
0131
0132 pollext = NDRX_MALLOC(sizeof(pollextension_rec_t));
0133 if (NULL==pollext)
0134 {
0135 ndrx_TPset_error_fmt(TPEOS, "failed to malloc pollextension_rec_t (%d bytes): %s",
0136 sizeof(pollextension_rec_t), strerror(errno));
0137 ret=EXFAIL;
0138 goto out;
0139 }
0140
0141 if (M_pollsync)
0142 {
0143
0144 ev.events = events;
0145 ev.data.fd = fd;
0146
0147 if (EXFAIL==ndrx_epoll_ctl(G_server_conf.epollfd, EX_EPOLL_CTL_ADD,
0148 fd, &ev))
0149 {
0150 ndrx_TPset_error_fmt(TPEOS, "epoll_ctl failed: %s",
0151 ndrx_poll_strerror(ndrx_epoll_errno()));
0152 ret=EXFAIL;
0153 goto out;
0154 }
0155 }
0156
0157
0158 pollext->p_pollevent = p_pollevent;
0159 pollext->fd = fd;
0160 pollext->ptr1 = ptr1;
0161
0162
0163
0164
0165
0166 DL_APPEND(ndrx_G_pollext, pollext);
0167 NDRX_LOG(log_debug, "Function 0x%lx fd=%d successfully added "
0168 "for polling", p_pollevent, fd);
0169
0170 out:
0171
0172
0173 if (EXSUCCEED!=ret && NULL!=pollext)
0174 {
0175 NDRX_FREE(pollext);
0176 }
0177
0178 return ret;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188 expublic int _tpext_delpollerfd(int fd)
0189 {
0190 int ret=EXSUCCEED;
0191 pollextension_rec_t * existing = NULL;
0192
0193 if (NULL==G_server_conf.service_array && M_pollsync)
0194 {
0195 ndrx_TPset_error_fmt(TPEPROTO, "Cannot remove custom poller at init stage!");
0196 ret=EXFAIL;
0197 goto out;
0198 }
0199
0200
0201 existing = ext_find_poller(fd);
0202 if (NULL==existing)
0203 {
0204 ndrx_TPset_error_fmt(TPEMATCH, "No polling extension found for fd %d", fd);
0205 ret=EXFAIL;
0206 goto out;
0207 }
0208
0209 if (M_pollsync)
0210 {
0211
0212 if (EXFAIL==ndrx_epoll_ctl(G_server_conf.epollfd, EX_EPOLL_CTL_DEL,
0213 fd, NULL))
0214 {
0215 ndrx_TPset_error_fmt(TPEOS, "epoll_ctl failed to remove fd %d from epollfd: %s",
0216 fd, ndrx_poll_strerror(ndrx_epoll_errno()));
0217 ret=EXFAIL;
0218 goto out;
0219 }
0220 }
0221
0222
0223 DL_DELETE(ndrx_G_pollext, existing);
0224 NDRX_FREE(existing);
0225
0226 out:
0227
0228 return ret;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237
0238 expublic int _tpext_addperiodcb(int secs, int (*p_periodcb)(void))
0239 {
0240 int ret=EXSUCCEED;
0241
0242 G_server_conf.p_periodcb = p_periodcb;
0243 G_server_conf.periodcb_sec = secs;
0244 NDRX_LOG(log_debug, "Registering periodic callback func ptr "
0245 "%p, period: %d sec(s)",
0246 G_server_conf.p_periodcb, G_server_conf.periodcb_sec);
0247
0248 out:
0249 return ret;
0250 }
0251
0252
0253
0254
0255
0256 expublic int _tpext_delperiodcb(void)
0257 {
0258 int ret=EXSUCCEED;
0259
0260 NDRX_LOG(log_debug, "Disabling periodical callback, was: %p",
0261 G_server_conf.p_periodcb);
0262 G_server_conf.p_periodcb = NULL;
0263 G_server_conf.periodcb_sec = 0;
0264 out:
0265 return ret;
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 expublic int _tpext_addb4pollcb(int (*p_b4pollcb)(void))
0277 {
0278 int ret=EXSUCCEED;
0279
0280 G_server_conf.p_b4pollcb = p_b4pollcb;
0281 NDRX_LOG(log_debug, "Registering before poll callback func ptr "
0282 "0x%lx",
0283 G_server_conf.p_b4pollcb);
0284
0285 out:
0286 return ret;
0287 }
0288
0289
0290
0291
0292
0293 expublic int _tpext_delb4pollcb(void)
0294 {
0295 int ret=EXSUCCEED;
0296
0297 NDRX_LOG(log_debug, "Disabling before poll callback, was: 0x%lx",
0298 G_server_conf.p_b4pollcb);
0299 G_server_conf.p_b4pollcb = NULL;
0300 out:
0301 return ret;
0302 }
0303
0304
0305
0306
0307
0308
0309
0310 expublic int ndrx_tpext_addbshutdowncb(int (*p_shutdowncb)(int *shutdown_req))
0311 {
0312 int ret=EXSUCCEED;
0313
0314 G_server_conf.p_shutdowncb = p_shutdowncb;
0315 NDRX_LOG(log_debug, "Registering shutdown func ptr %p", G_server_conf.p_shutdowncb);
0316
0317 out:
0318 return ret;
0319 }
0320
0321