~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/anvil/connect-limit.c

  • Committer: Package Import Robot
  • Author(s): Jaldhar H. Vyas
  • Date: 2013-09-09 00:57:32 UTC
  • mfrom: (1.13.11)
  • mto: (4.8.5 experimental) (1.16.1)
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: package-import@ubuntu.com-20130909005732-dn1eell8srqbhh0e
Tags: upstream-2.2.5
ImportĀ upstreamĀ versionĀ 2.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2009-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2009-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "common.h"
4
4
#include "hash.h"
15
15
};
16
16
 
17
17
struct connect_limit {
18
 
        /* ident => refcount */
19
 
        struct hash_table *ident_hash;
 
18
        /* ident => unsigned int refcount */
 
19
        HASH_TABLE(char *, void *) ident_hash;
20
20
        /* struct ident_pid => struct ident_pid */
21
 
        struct hash_table *ident_pid_hash;
 
21
        HASH_TABLE(struct ident_pid *, struct ident_pid *) ident_pid_hash;
22
22
};
23
23
 
24
 
static unsigned int ident_pid_hash(const void *p)
 
24
static unsigned int ident_pid_hash(const struct ident_pid *i)
25
25
{
26
 
        const struct ident_pid *i = p;
27
 
 
28
26
        return str_hash(i->ident) ^ i->pid;
29
27
}
30
28
 
31
 
static int ident_pid_cmp(const void *p1, const void *p2)
 
29
static int ident_pid_cmp(const struct ident_pid *i1, const struct ident_pid *i2)
32
30
{
33
 
        const struct ident_pid *i1 = p1, *i2 = p2;
34
 
 
35
31
        if (i1->pid < i2->pid)
36
32
                return -1;
37
33
        else if (i1->pid > i2->pid)
45
41
        struct connect_limit *limit;
46
42
 
47
43
        limit = i_new(struct connect_limit, 1);
48
 
        limit->ident_hash =
49
 
                hash_table_create(default_pool, default_pool, 0,
50
 
                                  str_hash, (hash_cmp_callback_t *)strcmp);
51
 
        limit->ident_pid_hash =
52
 
                hash_table_create(default_pool, default_pool, 0,
53
 
                                  ident_pid_hash, ident_pid_cmp);
 
44
        hash_table_create(&limit->ident_hash, default_pool, 0, str_hash, strcmp);
 
45
        hash_table_create(&limit->ident_pid_hash, default_pool, 0,
 
46
                          ident_pid_hash, ident_pid_cmp);
54
47
        return limit;
55
48
}
56
49
 
70
63
        void *value;
71
64
 
72
65
        value = hash_table_lookup(limit->ident_hash, ident);
73
 
        if (value == NULL)
74
 
                return 0;
75
 
 
76
66
        return POINTER_CAST_TO(value, unsigned int);
77
67
}
78
68
 
80
70
                           const char *ident)
81
71
{
82
72
        struct ident_pid *i, lookup_i;
83
 
        void *key, *value;
 
73
        char *key;
 
74
        void *value;
84
75
 
85
 
        if (!hash_table_lookup_full(limit->ident_hash, ident, &key, &value)) {
 
76
        if (!hash_table_lookup_full(limit->ident_hash, ident,
 
77
                                    &key, &value)) {
86
78
                key = i_strdup(ident);
87
79
                value = POINTER_CAST(1);
88
80
                hash_table_insert(limit->ident_hash, key, value);
108
100
static void
109
101
connect_limit_ident_hash_unref(struct connect_limit *limit, const char *ident)
110
102
{
111
 
        void *key, *value;
 
103
        char *key;
 
104
        void *value;
112
105
        unsigned int new_refcount;
113
106
 
114
107
        if (!hash_table_lookup_full(limit->ident_hash, ident, &key, &value))
150
143
void connect_limit_disconnect_pid(struct connect_limit *limit, pid_t pid)
151
144
{
152
145
        struct hash_iterate_context *iter;
153
 
        struct ident_pid *i;
154
 
        void *key, *value;
 
146
        struct ident_pid *i, *value;
155
147
 
156
148
        /* this should happen rarely (or never), so this slow implementation
157
149
           should be fine. */
158
150
        iter = hash_table_iterate_init(limit->ident_pid_hash);
159
 
        while (hash_table_iterate(iter, &key, &value)) {
160
 
                i = key;
 
151
        while (hash_table_iterate(iter, limit->ident_pid_hash, &i, &value)) {
161
152
                if (i->pid == pid) {
162
153
                        hash_table_remove(limit->ident_pid_hash, i);
163
154
                        for (; i->refcount > 0; i->refcount--)
171
162
void connect_limit_dump(struct connect_limit *limit, struct ostream *output)
172
163
{
173
164
        struct hash_iterate_context *iter;
174
 
        void *key, *value;
 
165
        struct ident_pid *i, *value;
175
166
        string_t *str = t_str_new(256);
176
167
 
177
168
        iter = hash_table_iterate_init(limit->ident_pid_hash);
178
 
        while (hash_table_iterate(iter, &key, &value)) {
179
 
                struct ident_pid *i = key;
180
 
 
 
169
        while (hash_table_iterate(iter, limit->ident_pid_hash, &i, &value)) {
181
170
                str_truncate(str, 0);
182
 
                str_tabescape_write(str, i->ident);
 
171
                str_append_tabescaped(str, i->ident);
183
172
                str_printfa(str, "\t%ld\t%u\n", (long)i->pid, i->refcount);
184
173
                if (o_stream_send(output, str_data(str), str_len(str)) < 0)
185
174
                        break;
186
175
        }
187
176
        hash_table_iterate_deinit(&iter);
188
 
        (void)o_stream_send(output, "\n", 1);
 
177
        o_stream_nsend(output, "\n", 1);
189
178
}