File: rateGovernor.c

package info (click to toggle)
udpcast 20100130-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 856 kB
  • sloc: ansic: 7,530; sh: 2,838; perl: 227; makefile: 114
file content (122 lines) | stat: -rw-r--r-- 2,622 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#include "log.h"
#include "fifo.h"
#include "socklib.h"
#include "udpcast.h"
#include "rateGovernor.h"

#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#if defined HAVE_DLSYM && defined NO_BB
#define DL_RATE_GOVERNOR
#endif

void *rgInitGovernor(struct net_config *cfg, struct rateGovernor_t *gov)
{
  if(cfg->nrGovernors == MAX_GOVERNORS) {
    fprintf(stderr, "Too many rate governors\n");
    exit(1);
  }
  cfg->rateGovernor[cfg->nrGovernors] = gov;
  return cfg->rateGovernorData[cfg->nrGovernors++] =  gov->rgInitialize();
}

#ifdef DL_RATE_GOVERNOR
void rgParseRateGovernor(struct net_config *net_config, char *rg)
{
    char *pos = strchr(rg, ':');
    char *dlname;
    char *params;
    char *error;
    void *rgdl;
    struct rateGovernor_t *gov;
    void *data;

    if(pos) {
	dlname = strndup(rg, pos-rg);
	params = pos+1;
    } else {
	dlname = rg;
	params = NULL;
    }

    rgdl = dlopen(dlname, RTLD_LAZY);
    if(rgdl == NULL) {
	fprintf(stderr, "Library load error %s\n", dlerror());
	exit(1);
    }
    dlerror(); /* Clear any existing error */

    gov = dlsym(rgdl, "governor");
    if ((error = dlerror()) != NULL)  {
	fprintf(stderr, "Symbol resolve error: %s\n", error);
	exit(1);
    }

    if(pos)
	free(dlname);

    data = rgInitGovernor(net_config, gov);

    if(net_config->rateGovernorData == NULL) {
	fprintf(stderr, "Rate governor initialization error\n");
	exit(1);
    }

    if(gov->rgSetProp) {
      while(params && *params) {
	char *eqPos; /* Position of the equal sign */
	const char *key; /* Property name */
	const char *value; /* property value */
	pos = strchr(params, ',');
	if(pos == NULL)
	  pos = params + strlen(params);
	eqPos = strchr(params, '=');
	if(eqPos == NULL || eqPos >= pos) {
	  key = strndup(params, pos-params);
	  value = NULL;
	} else {
	  key = strndup(params, eqPos-params);
	  value = strndup(eqPos+1, pos-(eqPos+1));
	}
	gov->rgSetProp(data, key, value);
	if(*pos)
	  pos++;
	params=pos;
      }
    }
    if(gov->rgEndConfig) {
      gov->rgEndConfig(data);
    }
}
#endif

void rgWaitAll(struct net_config *cfg, int sock, in_addr_t ip, int size)
{
  int i=0;
  for(i=0; i<cfg->nrGovernors; i++) {
    cfg->rateGovernor[i]->rgWait(cfg->rateGovernorData[i], sock, ip, size);
  }
}

void rgShutdownAll(struct net_config *cfg)
{
  int i=0;
  for(i=0; i<cfg->nrGovernors; i++) {
    if(cfg->rateGovernor[i]->rgShutdown)
	cfg->rateGovernor[i]->rgShutdown(cfg->rateGovernorData[i]);
  }
}