Duncan Bellamy:
> Hi,
> 
> This patch is based on the original code by Titus Jose on GitHub, I
> updated it to work with the development branch and have added some
> documentation.

Thanks.  I have a few suggestions regarding memory leaks, data
owbership, and testing.

115 static const char *dict_redis_lookup(DICT *dict, const char *name)
116 {
...
124     result = vstring_alloc(10);
125     VSTRING_RESET(result);      /* Not needed -- WZV */
126     VSTRING_TERMINATE(result);  /* Not needed -- WZV */

I think that you're leaking one VSTRING per dict_redis_lookup()
call. With the Postfix DICT variants, a dictionary owns the lookup
result (no multi-threading), it is therefore OK to make the result
a member of the DICT_REDIS instance.

141     if(dict_redis->c) {
142         reply = redisCommand(dict_redis->c,"GET %s%s",dict_redis->prefix    
142 ,name);
143     }
144     else {      /* Can't happen - WZV */
145         dict->error = DICT_ERR_CONFIG;
146     }

The code in dict_redis_open guarantees that a DICT_REDIS instance
never has null DICT_REDIS.c member. You can delete the test and the
unreachable branch.

172 DICT   *dict_redis_open(const char *name, int open_flags, int dict_flags
172 )
173 {
...
193     c = redisConnect(dict_redis->host,dict_redis->port);
194     if(c->err) {        /* Redirect to surrogate -- WZV */
195         msg_fatal("%s:%s: Cannot connect to Redis server %s: %s\n",
196             DICT_TYPE_REDIS, name, dict_redis->host, c->errstr);

For consistency with other code, this should

1) Free the 'c' 
2) Set dict_redis->c to null and invoke dict_close(&dict_redis)
3) Return dict_surrogate(DICT_TYPE_REDIS, name, ...)

206 static void dict_redis_close(DICT *dict)
207 {
208     DICT_REDIS *dict_redis = (DICT_REDIS *) dict;

This function leaks the dict_redis->c pointer.
Here, call free dict_redis->c if it is not null.

Be sure to test this under VALGRIND. See Makefile 
for how to build and run mail_dict.c.

        Wietse

Reply via email to