Skip to content

Commit 9ceadad

Browse files
committed
Moved include to src, updated store_destroy routine
1 parent 6ad36a1 commit 9ceadad

File tree

9 files changed

+230
-41
lines changed

9 files changed

+230
-41
lines changed

CMakeLists.txt

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 2.8)
22

33
project(sol)
4-
set (VERSION 0.18.3)
4+
set (VERSION 0.18.5)
55
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
66

77
OPTION(DEBUG "add debug flags" OFF)
@@ -11,7 +11,6 @@ find_package(OpenSSL REQUIRED)
1111

1212
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
1313

14-
include_directories(include)
1514
file(GLOB SOURCES src/*.c)
1615
file(GLOB TEST src/hashtable.c src/bst.c src/config.c src/list.c src/trie.c
1716
src/util.c src/iterator.c src/logging.c src/memory.c tests/*.c)
@@ -20,7 +19,7 @@ set(AUTHOR "Andrea Giacomo Baldan")
2019
set(LICENSE "BSD2 license")
2120

2221
# Executable
23-
add_executable(sol ${SOURCES} include/uthash.h include/ref.h)
22+
add_executable(sol ${SOURCES})
2423
add_executable(sol_test ${TEST})
2524

2625
if (DEBUG)

src/config.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* BSD 2-Clause License
22
*
3-
* Copyright (c) 2019, Andrea Giacomo Baldan All rights reserved.
3+
* Copyright (c) 2020, Andrea Giacomo Baldan All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
66
* modification, are permitted provided that the following conditions are met:
@@ -63,7 +63,7 @@
6363

6464
// Default parameters
6565

66-
#define VERSION "0.18.3"
66+
#define VERSION "0.18.5"
6767
#define DEFAULT_SOCKET_FAMILY INET
6868
#define DEFAULT_LOG_LEVEL DEBUG
6969
#define DEFAULT_CONF_PATH "/etc/sol/sol.conf"

include/ref.h renamed to src/ref.h

File renamed without changes.

src/server.c

+8-7
Original file line numberDiff line numberDiff line change
@@ -248,55 +248,55 @@ static void publish_stats(struct ev_ctx *ctx, void *data) {
248248
}
249249
};
250250

251-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
251+
publish_message(&p, topic_store_get(server.store, sys_topics[2].name));
252252

253253
// $SOL/broker/uptime/sol
254254
p.publish.topiclen = sys_topics[3].len;
255255
p.publish.topic = (unsigned char *) sys_topics[3].name;
256256
p.publish.payloadlen = strlen(sutime);
257257
p.publish.payload = (unsigned char *) &sutime;
258258

259-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
259+
publish_message(&p, topic_store_get(server.store, sys_topics[3].name));
260260

261261
// $SOL/broker/clients/connected
262262
p.publish.topiclen = sys_topics[4].len;
263263
p.publish.topic = (unsigned char *) sys_topics[4].name;
264264
p.publish.payloadlen = strlen(cclients);
265265
p.publish.payload = (unsigned char *) &cclients;
266266

267-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
267+
publish_message(&p, topic_store_get(server.store, sys_topics[4].name));
268268

269269
// $SOL/broker/bytes/sent
270270
p.publish.topiclen = sys_topics[6].len;
271271
p.publish.topic = (unsigned char *) sys_topics[6].name;
272272
p.publish.payloadlen = strlen(bsent);
273273
p.publish.payload = (unsigned char *) &bsent;
274274

275-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
275+
publish_message(&p, topic_store_get(server.store, sys_topics[6].name));
276276

277277
// $SOL/broker/messages/sent
278278
p.publish.topiclen = sys_topics[8].len;
279279
p.publish.topic = (unsigned char *) sys_topics[8].name;
280280
p.publish.payloadlen = strlen(msent);
281281
p.publish.payload = (unsigned char *) &msent;
282282

283-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
283+
publish_message(&p, topic_store_get(server.store, sys_topics[8].name));
284284

285285
// $SOL/broker/messages/received
286286
p.publish.topiclen = sys_topics[9].len;
287287
p.publish.topic = (unsigned char *) sys_topics[9].name;
288288
p.publish.payloadlen = strlen(mrecv);
289289
p.publish.payload = (unsigned char *) &mrecv;
290290

291-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
291+
publish_message(&p, topic_store_get(server.store, sys_topics[9].name));
292292

293293
// $SOL/broker/memory/used
294294
p.publish.topiclen = sys_topics[10].len;
295295
p.publish.topic = (unsigned char *) sys_topics[10].name;
296296
p.publish.payloadlen = strlen(mem);
297297
p.publish.payload = (unsigned char *) &mem;
298298

299-
publish_message(&p, topic_store_get(server.store, (char *) p.publish.topic));
299+
publish_message(&p, topic_store_get(server.store, sys_topics[10].name));
300300
}
301301

302302
/*
@@ -982,6 +982,7 @@ int start_server(const char *addr, const char *port) {
982982

983983
close(sfd);
984984
AUTH_DESTROY(server.authentications);
985+
topic_store_destroy(server.store);
985986

986987
/* Destroy SSL context, if any present */
987988
if (conf->tls == true) {

src/sol_internal.h

+95-9
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ struct topic {
8888
*/
8989
struct topic_store {
9090
// The main topics Trie structure
91-
Trie topics;
91+
Trie *topics;
9292
// A list of wildcards subscriptions, as it's not possible to know in
9393
// advance what topics will match some wildcard subscriptions
9494
List *wildcards;
@@ -238,35 +238,121 @@ extern pthread_mutex_t mutex;
238238
struct server;
239239

240240
bool is_subscribed(const struct topic *, const struct client_session *);
241+
241242
struct subscriber *subscriber_new(struct topic *,
242243
struct client_session *, unsigned char);
244+
243245
struct subscriber *subscriber_clone(const struct subscriber *);
244-
struct subscriber *topic_add_subscriber(struct topic *,
245-
struct client_session *, unsigned char);
246246

247+
/*
248+
* Initialize a struct topic pointer by setting its name, subscribers and
249+
* retained_msg are set to NULL.
250+
* The function expects a non-null pointer and can't fail, if a null topic
251+
* is passed, the function return prematurely.
252+
*/
247253
void topic_init(struct topic *, const char *);
254+
255+
/*
256+
* Allocate a new topic struct on the heap, initialize it then return a pointer
257+
* to it. The function can fail as a memory allocation is requested, if it
258+
* fails the program execution graceful crash.
259+
*/
248260
struct topic *topic_new(const char *);
261+
262+
/*
263+
* Deallocate the topic name, retained_msg and all its subscribers
264+
*/
265+
void topic_destroy(struct topic *);
266+
267+
/*
268+
* Allocate a new subscriber struct on the heap referring to the passed in
269+
* topic, client_session and QoS, then add it to the topic map.
270+
* The function can fail as a memory allocation is requested, if it fails the
271+
* program execution graceful crash.
272+
*/
273+
struct subscriber *topic_add_subscriber(struct topic *,
274+
struct client_session *, unsigned char);
275+
276+
/*
277+
* Remove a subscriber from the topic, the subscriber to be removed refers to
278+
* the client_id belonging to the client pointer passed in.
279+
* The subscriber deletion is really a reference count subtraction, DECREF
280+
* macro takes care of the counter, if it reaches 0 it de-allocates the memory
281+
* reserved to the struct subscriber.
282+
* The function can't fail.
283+
*/
249284
void topic_del_subscriber(struct topic *, struct client *);
285+
286+
/*
287+
* Allocate a new store structure on the heap and return it after its
288+
* initialization, also allocating a new list on the heap to keep track of
289+
* wildcard topics.
290+
* The function may gracefully crash as the memory allocation may fail.
291+
*/
250292
struct topic_store *topic_store_new(void);
251-
/* Find a topic by name and return it */
293+
294+
/*
295+
* Deallocate heap memory for the list and every wildcard item stored into,
296+
* also the store is deallocated
297+
*/
298+
void topic_store_destroy(struct topic_store *);
299+
300+
/*
301+
* Return a topic associated to a topic name from the store, returns NULL if no
302+
* topic is found.
303+
*/
252304
struct topic *topic_store_get(const struct topic_store *, const char *);
253-
/* Get or create a new topic if it doesn't exists */
305+
306+
/*
307+
* Return a topic associated to a topic name from the store, if no topic is
308+
* insert it into the store before returning it. Like topic_store_get but
309+
* cannot return NULL.
310+
* The function may fail as in case of no topic found it tries to allocate
311+
* space on the heap for the new inserted topic.
312+
*/
254313
struct topic *topic_store_get_or_put(struct topic_store *, const char *);
314+
315+
/*
316+
* Check if the store contains a topic by name key
317+
*/
255318
bool topic_store_contains(const struct topic_store *, const char *);
319+
320+
/*
321+
* Insert a topic into the store or update it if already present
322+
*/
256323
void topic_store_put(struct topic_store *, struct topic *);
324+
325+
/*
326+
* Remove a topic into the store
327+
*/
257328
void topic_store_del(struct topic_store *, const char *);
329+
330+
/*
331+
* Add a wildcard topic to the topic_store struct, does not check if it already
332+
* exists
333+
*/
258334
void topic_store_add_wildcard(struct topic_store *, struct subscription *);
335+
336+
/*
337+
* Remove a wildcard by id key from the topic_store struct
338+
*/
259339
void topic_store_remove_wildcard(struct topic_store *, char *);
340+
341+
/*
342+
* Run a function to each node of the topic_store trie holding the topic
343+
* entries
344+
*/
260345
void topic_store_map(struct topic_store *, const char *,
261346
void (*fn)(struct trie_node *, void *), void *);
347+
348+
/*
349+
* Check if the wildcards list of the topic_store is empty
350+
*/
262351
bool topic_store_wildcards_empty(const struct topic_store *);
263352

264353
#define topic_store_wildcards_foreach(item, store) \
265354
list_foreach(item, store->wildcards)
266355

267-
/* unsigned next_free_mid(struct client_session *); */
268-
/* void session_init(struct client_session *, const char *); */
269-
/* struct client_session *client_session_alloc(const char *); */
270-
271356
#define has_inflight(session) ((session)->inflights > 0)
357+
272358
#define inflight_msg_clear(msg) DECREF((msg)->packet, struct mqtt_packet)

src/topic.c

+49-2
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,59 @@
2828
#include "memory.h"
2929
#include "sol_internal.h"
3030

31+
/*
32+
* Initialize a struct topic pointer by setting its name, subscribers and
33+
* retained_msg are set to NULL.
34+
* The function expects a non-null pointer and can't fail, if a null topic
35+
* is passed, the function return prematurely.
36+
*/
3137
void topic_init(struct topic *t, const char *name) {
38+
if (!t)
39+
return;
3240
t->name = name;
3341
t->subscribers = NULL;
3442
t->retained_msg = NULL;
3543
}
3644

45+
/*
46+
* Allocate a new topic struct on the heap, initialize it then return a pointer
47+
* to it. The function can fail as a memory allocation is requested, if it
48+
* fails the program execution graceful crash.
49+
*/
3750
struct topic *topic_new(const char *name) {
38-
if (!name)
39-
return NULL;
4051
struct topic *t = try_alloc(sizeof(*t));
4152
topic_init(t, name);
4253
return t;
4354
}
4455

56+
/*
57+
* Deallocate the topic name, retained_msg and all its subscribers
58+
*/
59+
void topic_destroy(struct topic *t) {
60+
if (!t)
61+
return;
62+
free_memory((void *) t->name);
63+
free_memory(t->retained_msg);
64+
if (!t->subscribers) {
65+
free_memory(t);
66+
return;
67+
}
68+
struct subscriber *sub, *dummy;
69+
HASH_ITER(hh, t->subscribers, sub, dummy) {
70+
if (!sub)
71+
continue;
72+
HASH_DEL(t->subscribers, sub);
73+
free_memory(sub);
74+
}
75+
free_memory(t);
76+
}
77+
78+
/*
79+
* Allocate a new subscriber struct on the heap referring to the passed in
80+
* topic, client_session and QoS, then add it to the topic map.
81+
* The function can fail as a memory allocation is requested, if it fails the
82+
* program execution graceful crash.
83+
*/
4584
struct subscriber *topic_add_subscriber(struct topic *t,
4685
struct client_session *s,
4786
unsigned char qos) {
@@ -52,6 +91,14 @@ struct subscriber *topic_add_subscriber(struct topic *t,
5291
return sub;
5392
}
5493

94+
/*
95+
* Remove a subscriber from the topic, the subscriber to be removed refers to
96+
* the client_id belonging to the client pointer passed in.
97+
* The subscriber deletion is really a reference count subtraction, DECREF
98+
* macro takes care of the counter, if it reaches 0 it de-allocates the memory
99+
* reserved to the struct subscriber.
100+
* The function can't fail.
101+
*/
55102
void topic_del_subscriber(struct topic *t, struct client *c) {
56103
struct subscriber *sub = NULL;
57104
HASH_FIND_STR(t->subscribers, c->client_id, sub);

0 commit comments

Comments
 (0)