Skip to content

Commit 11a2eae

Browse files
authored
Update samples, make C++/Qt threadsafe
Samples updated to changes in pubnub_cancel() and other interface changes and to use time() instead of clock() as clock() can measure CPU-only time instead of real time. Update Qt functional tests and make them reliable. UUID is now part of the Pubnub context (instead of a pointer to it). This makes handling its lifetime easier, yet doesn't incur much memory increase. C++ wrapper and Qt did not have proper multithreading support as they didn't protect _their_ data. C protects its own context, but, that doesn't include stuff in the C++ context (such as `auth` key and the message to publish via POST).
1 parent 496b953 commit 11a2eae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1514
-782
lines changed

.appveyor.yml

+13
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,33 @@ platform:
55
environment:
66
matrix:
77
- BUILD_TYPE: nmake
8+
QT5: C:\Qt\5.11\mingw53_32
9+
MINGW: C:\Qt\Tools\mingw530_32
810

11+
before_build:
12+
- set PATH=%MINGW%\bin;%QT5%\bin;%PATH%
913

1014
build_script:
1115
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat"
1216
- nmake /f windows.mk
1317
- cd core
1418
- nmake /f W_makefile.mk
1519
- cd ..
20+
- cd qt
21+
- qmake fn_test.pro CONFIG+=release DESTDIR=. &&
22+
mingw32-make &&
23+
qmake pubnub.pro CONFIG+=release DESTDIR=. &&
24+
mingw32-make &&
25+
qmake pubnub_gui.pro CONFIG+=release DESTDIR=. &&
26+
mingw32-make
27+
- cd ..
1628

1729
test_script:
1830
- core\pubnub_proxy_NTLM_test
1931
- windows\pubnub_fntest
2032
- openssl\pubnub_fntest
2133
- cpp\fntest_runner
2234
- cpp\openssl\fntest_runner
35+
- qt\release\fn_test
2336

2437
deploy: off

.pubnub.yml

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
name: c-core
2-
version: 2.6.2
2+
version: 2.6.3
33
scm: github.com/pubnub/c-core
44
changelog:
5+
- version: v2.6.3
6+
changes:
7+
- type: enhancement
8+
text: Update samples to changes in pubnub_cancel() and other interface changes
9+
- type: enhancement
10+
text: Update samples to use time() instead of clock() as clock() can measure CPU-only time instead of real time
11+
- type: enhancement
12+
text: Update Qt functional tests and make them reliable
13+
- type: enhancement
14+
text: UUID is now part of the Pubnub context (instead of a pointer to it). This makes handling its lifetime easier, yet doesn't incur much memory increase
15+
- type: bug
16+
text: C++ wrapper and Qt did not have proper multithreading support as they didn't protect _their_ data. Now that's fixed.
517
- version: v2.6.2
618
changes:
719
- type: bug

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ In this root directory we have some files, too:
4242
Makefiles there are (doesn't build Qt - you might not have Qt)
4343
- `windows.mk`: a "master" Makefile for Windows - will build all the
4444
Windows Makefiles there are (doesn't build Qt, you might not have Qt)
45-
- `VERSION`: Identifies the latest stable / recommended release
4645
- `.pubnub.yml`: Standard Pubnub library description in YAML
46+
- `.travis.yml`: Configuration for Travis CI (POSIX: Linux and MacOS)
47+
- `.appveyor.yml`: Configuration for Appveyor CI (Windows)
48+
- `.clang-format`: Configuration for Clang-format tool that we use to format
49+
C/C++ source code
4750

4851

4952
## Contributing

core/pubnub_ccore.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ enum pubnub_res pbcc_leave_prep(struct pbcc_context* pb,
100100
const char* channel,
101101
const char* channel_group)
102102
{
103+
char const* uuid = pbcc_uuid_get(pb);
104+
103105
if (NULL == channel) {
104106
if (NULL == channel_group) {
105107
return PNR_INVALID_CHANNEL;
@@ -120,7 +122,7 @@ enum pubnub_res pbcc_leave_prep(struct pbcc_context* pb,
120122
channel,
121123
pubnub_uname());
122124
APPEND_URL_PARAM_M(pb, "channel-group", channel_group, '&');
123-
APPEND_URL_PARAM_M(pb, "uuid", pb->uuid, '&');
125+
APPEND_URL_PARAM_M(pb, "uuid", uuid, '&');
124126
APPEND_URL_PARAM_M(pb, "auth", pb->auth, '&');
125127

126128
return PNR_STARTED;
@@ -129,6 +131,8 @@ enum pubnub_res pbcc_leave_prep(struct pbcc_context* pb,
129131

130132
enum pubnub_res pbcc_time_prep(struct pbcc_context* pb)
131133
{
134+
char const* uuid = pbcc_uuid_get(pb);
135+
132136
if (pb->msg_ofs < pb->msg_end) {
133137
return PNR_RX_BUFF_NOT_EMPTY;
134138
}
@@ -138,7 +142,7 @@ enum pubnub_res pbcc_time_prep(struct pbcc_context* pb)
138142

139143
pb->http_buf_len = snprintf(
140144
pb->http_buf, sizeof pb->http_buf, "/time/0?pnsdk=%s", pubnub_uname());
141-
APPEND_URL_PARAM_M(pb, "uuid", pb->uuid, '&');
145+
APPEND_URL_PARAM_M(pb, "uuid", uuid, '&');
142146
APPEND_URL_PARAM_M(pb, "auth", pb->auth, '&');
143147

144148
return PNR_STARTED;
@@ -183,6 +187,8 @@ enum pubnub_res pbcc_heartbeat_prep(struct pbcc_context* pb,
183187
const char* channel,
184188
const char* channel_group)
185189
{
190+
char const* uuid = pbcc_uuid_get(pb);
191+
186192
if (NULL == channel) {
187193
if (NULL == channel_group) {
188194
return PNR_INVALID_CHANNEL;
@@ -205,7 +211,7 @@ enum pubnub_res pbcc_heartbeat_prep(struct pbcc_context* pb,
205211
pubnub_uname());
206212
APPEND_URL_PARAM_M(pb, "channel-group", channel_group, '&');
207213
APPEND_URL_PARAM_M(pb, "auth", pb->auth, '&');
208-
APPEND_URL_PARAM_M(pb, "uuid", pb->uuid, '&');
214+
APPEND_URL_PARAM_M(pb, "uuid", uuid, '&');
209215

210216
return PNR_STARTED;
211217
}
@@ -217,6 +223,8 @@ enum pubnub_res pbcc_here_now_prep(struct pbcc_context* pb,
217223
enum pubnub_tribool disable_uuids,
218224
enum pubnub_tribool state)
219225
{
226+
char const* uuid = pbcc_uuid_get(pb);
227+
220228
if (NULL == channel) {
221229
if (channel_group != NULL) {
222230
channel = ",";
@@ -238,7 +246,7 @@ enum pubnub_res pbcc_here_now_prep(struct pbcc_context* pb,
238246
pubnub_uname());
239247
APPEND_URL_PARAM_M(pb, "channel-group", channel_group, '&');
240248
APPEND_URL_PARAM_M(pb, "auth", pb->auth, '&');
241-
APPEND_URL_PARAM_M(pb, "uuid", pb->uuid, '&');
249+
APPEND_URL_PARAM_M(pb, "uuid", uuid, '&');
242250
APPEND_URL_PARAM_TRIBOOL_M(pb, "disable_uuids", disable_uuids, '&');
243251
APPEND_URL_PARAM_TRIBOOL_M(pb, "state", state, '&');
244252

core/pubnub_ccore_pubsub.c

+21-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ void pbcc_init(struct pbcc_context* p, const char* publish_key, const char* subs
1717
p->subscribe_key = subscribe_key;
1818
p->timetoken[0] = '0';
1919
p->timetoken[1] = '\0';
20-
p->uuid = p->auth = NULL;
20+
p->uuid[0] = '\0';
21+
p->auth = NULL;
2122
p->msg_ofs = p->msg_end = 0;
2223
#if PUBNUB_DYNAMIC_REPLY_BUFFER
2324
p->http_reply = NULL;
@@ -114,7 +115,20 @@ char const* pbcc_get_channel(struct pbcc_context* pb)
114115

115116
void pbcc_set_uuid(struct pbcc_context* pb, const char* uuid)
116117
{
117-
pb->uuid = uuid;
118+
if (uuid != NULL) {
119+
PUBNUB_ASSERT_OPT(strlen(uuid) < sizeof pb->uuid);
120+
strncpy(pb->uuid, uuid, sizeof pb->uuid);
121+
pb->uuid[(sizeof pb->uuid) - 1] = '\0';
122+
}
123+
else {
124+
pb->uuid[0] = '\0';
125+
}
126+
}
127+
128+
129+
char const* pbcc_uuid_get(struct pbcc_context* pb)
130+
{
131+
return ('\0' == pb->uuid[0]) ? NULL : pb->uuid;
118132
}
119133

120134

@@ -424,6 +438,7 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb,
424438
enum pubnub_publish_method method)
425439
{
426440
char const* const uname = pubnub_uname();
441+
char const* uuid = pbcc_uuid_get(pb);
427442
enum pubnub_res rslt = PNR_OK;
428443

429444
PUBNUB_ASSERT_OPT(message != NULL);
@@ -447,7 +462,7 @@ enum pubnub_res pbcc_publish_prep(struct pbcc_context* pb,
447462
pb->message_to_publish = message;
448463
}
449464
APPEND_URL_PARAM_M(pb, "pnsdk", uname, '?');
450-
APPEND_URL_PARAM_M(pb, "uuid", pb->uuid, '&');
465+
APPEND_URL_PARAM_M(pb, "uuid", uuid, '&');
451466
APPEND_URL_PARAM_M(pb, "auth", pb->auth, '&');
452467
if ((PNR_OK == rslt) && !store_in_history) {
453468
rslt = pbcc_append_url_param(pb, "store", sizeof "store" - 1, "0", '&');
@@ -476,6 +491,8 @@ enum pubnub_res pbcc_subscribe_prep(struct pbcc_context* p,
476491
char const* channel_group,
477492
unsigned* heartbeat)
478493
{
494+
char const* uuid = pbcc_uuid_get(p);
495+
479496
if (NULL == channel) {
480497
if (NULL == channel_group) {
481498
return PNR_INVALID_CHANNEL;
@@ -497,7 +514,7 @@ enum pubnub_res pbcc_subscribe_prep(struct pbcc_context* p,
497514
p->timetoken,
498515
pubnub_uname());
499516
APPEND_URL_PARAM_M(p, "channel-group", channel_group, '&');
500-
APPEND_URL_PARAM_M(p, "uuid", p->uuid, '&');
517+
APPEND_URL_PARAM_M(p, "uuid", uuid, '&');
501518
APPEND_URL_PARAM_M(p, "auth", p->auth, '&');
502519
APPEND_URL_OPT_PARAM_UNSIGNED_M(p, "heartbeat", heartbeat, '&');
503520

core/pubnub_ccore_pubsub.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "pubnub_config.h"
66
#include "pubnub_api_types.h"
7+
#include "pubnub_generate_uuid.h"
78

89
#include <stdbool.h>
910
#include <stdlib.h>
@@ -24,8 +25,8 @@ struct pbcc_context {
2425
char const* publish_key;
2526
/** The subscribe key (to use when subscribing) */
2627
char const* subscribe_key;
27-
/** The UUID to be sent to server. If NULL, don't send any */
28-
char const* uuid;
28+
/** The UUID to be sent to server. If empty string, don't send any */
29+
char uuid[UUID_SIZE];
2930
/** The `auth` parameter to be sent to server. If NULL, don't send
3031
* any */
3132
char const* auth;
@@ -113,7 +114,7 @@ struct pbcc_context {
113114
if ((var) != NULL) { \
114115
const char param_[] = name; \
115116
enum pubnub_res rslt_ = pbcc_append_url_param( \
116-
(pbc), param_, sizeof param_ - 1, (var), (separator)); \
117+
(pbc), param_, sizeof param_ - 1, (var), (separator)); \
117118
if (rslt_ != PNR_OK) { \
118119
return rslt_; \
119120
} \
@@ -123,7 +124,7 @@ struct pbcc_context {
123124
if ((var) != NULL) { \
124125
const char param_[] = name; \
125126
enum pubnub_res rslt_ = pbcc_append_url_param_encoded( \
126-
(pbc), param_, sizeof param_ - 1, (var), (separator)); \
127+
(pbc), param_, sizeof param_ - 1, (var), (separator)); \
127128
if (rslt_ != PNR_OK) { \
128129
return rslt_; \
129130
} \
@@ -200,6 +201,9 @@ char const* pbcc_get_channel(struct pbcc_context* pb);
200201
/** Sets the UUID for the context */
201202
void pbcc_set_uuid(struct pbcc_context* pb, const char* uuid);
202203

204+
/** Returns the UUID for the context */
205+
char const* pbcc_uuid_get(struct pbcc_context* pb);
206+
203207
/** Sets the `auth` for the context */
204208
void pbcc_set_auth(struct pbcc_context* pb, const char* auth);
205209

core/pubnub_coreapi.c

+17-3
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ enum pubnub_res pubnub_where_now(pubnub_t* pb, const char* uuid)
189189
return PNR_IN_PROGRESS;
190190
}
191191

192-
rslt = pbcc_where_now_prep(&pb->core, uuid ? uuid : pb->core.uuid);
192+
rslt = pbcc_where_now_prep(&pb->core, uuid ? uuid : pbcc_uuid_get(&pb->core));
193193
if (PNR_STARTED == rslt) {
194194
pb->trans = PBTT_WHERENOW;
195195
pb->core.last_result = PNR_STARTED;
@@ -219,7 +219,7 @@ enum pubnub_res pubnub_set_state(pubnub_t* pb,
219219
}
220220

221221
rslt = pbcc_set_state_prep(
222-
&pb->core, channel, channel_group, uuid ? uuid : pb->core.uuid, state);
222+
&pb->core, channel, channel_group, uuid ? uuid : pbcc_uuid_get(&pb->core), state);
223223
if (PNR_STARTED == rslt) {
224224
pb->trans = PBTT_SET_STATE;
225225
pb->core.last_result = PNR_STARTED;
@@ -248,7 +248,7 @@ enum pubnub_res pubnub_state_get(pubnub_t* pb,
248248
}
249249

250250
rslt = pbcc_state_get_prep(
251-
&pb->core, channel, channel_group, uuid ? uuid : pb->core.uuid);
251+
&pb->core, channel, channel_group, uuid ? uuid : pbcc_uuid_get(&pb->core));
252252
if (PNR_STARTED == rslt) {
253253
pb->trans = PBTT_STATE_GET;
254254
pb->core.last_result = PNR_STARTED;
@@ -363,3 +363,17 @@ enum pubnub_res pubnub_list_channel_group(pubnub_t* pb, char const* channel_grou
363363
pubnub_mutex_unlock(pb->monitor);
364364
return rslt;
365365
}
366+
367+
368+
bool pubnub_can_start_transaction(pubnub_t* pb)
369+
{
370+
bool rslt;
371+
372+
PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));
373+
374+
pubnub_mutex_lock(pb->monitor);
375+
rslt = pbnc_can_start_transaction(pb);
376+
pubnub_mutex_unlock(pb->monitor);
377+
378+
return rslt;
379+
}

core/pubnub_coreapi.h

+16-9
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ enum pubnub_res pubnub_leave(pubnub_t *p, const char *channel, const char *chann
7171
If transaction is successful, the gotten time will be the only
7272
message you can get with pubnub_get(). It will be a (large) JSON
7373
integer.
74-
74+
7575
You can't get time if a transaction is in progress on the context.
7676
7777
@param p The Pubnub context. Can't be NULL.
@@ -94,11 +94,11 @@ enum pubnub_res pubnub_time(pubnub_t *p);
9494
rather an array of JSON objects, having keys `message` with
9595
value the actual message, and `timetoken` with the time token
9696
of that particular message.
97-
97+
9898
You can't get history if a transaction is in progress on the context.
9999
100-
@param p The Pubnub context. Can't be NULL.
101-
@param channel The string with the channel name to get message
100+
@param p The Pubnub context. Can't be NULL.
101+
@param channel The string with the channel name to get message
102102
history for. This _can't_ be a comma separated list of channels.
103103
@param count Maximum number of messages to get. If there are less
104104
than this available on the @c channel, you'll get less, but you
@@ -126,7 +126,7 @@ enum pubnub_res pubnub_history(pubnub_t *p, const char *channel, unsigned count,
126126
you will subscribe only to the channel group(s). It goes both ways:
127127
if @p channel_group is NULL, then @p channel cannot be NULL and
128128
you will subscribe only to the channel(s).
129-
129+
130130
You can't get list of currently present users if a transaction is
131131
in progress on the context.
132132
@@ -171,7 +171,7 @@ enum pubnub_res pubnub_heartbeat(pubnub_t *p, const char* channel, const char* c
171171
you will subscribe only to the channel group(s). It goes both ways:
172172
if @p channel_group is NULL, then @p channel cannot be NULL and
173173
you will subscribe only to the channel(s).
174-
174+
175175
You can't get list of currently present users if a transaction is
176176
in progress on the context.
177177
@@ -193,7 +193,7 @@ enum pubnub_res pubnub_here_now(pubnub_t *p, const char *channel, const char *ch
193193
If transaction is successful, the response will be the same
194194
as for "multi-channel" response for pubnub_here_now(), if
195195
we queried against all currently available channels.
196-
196+
197197
You can't get list of currently present users if a transaction is
198198
in progress on the context.
199199
@@ -277,9 +277,9 @@ enum pubnub_res pubnub_set_state(pubnub_t *p, char const *channel, char const *c
277277
- "status": the HTTP status of the operation (200 OK, 40x error, etc.)
278278
- "message": the string/message describing the status ("OK"...)
279279
- "service": should be "Presence"
280-
- "payload": if querying against one channel the gotten state
280+
- "payload": if querying against one channel - the state we got
281281
(a JSON object), otherwise a JSON object with the key "channels"
282-
whose value is a JSON object with keys the name of the channels
282+
whose value is a JSON object having keys the name of each channels
283283
and their respective values JSON objects of the gotten state
284284
285285
If @p channel is NULL, then @p channel_group cannot be NULL and
@@ -401,6 +401,13 @@ enum pubnub_res pubnub_add_channel_to_group(pubnub_t *p, char const *channel, ch
401401
*/
402402
enum pubnub_res pubnub_list_channel_group(pubnub_t *p, char const *channel_group);
403403

404+
/** Checks if a transaction can be started on @p pb context. In other
405+
words, checks if previous transaction is finished.
406+
407+
@retval true can start new transaction
408+
@retval false otherwise (cannot start a new transaction)
409+
*/
410+
bool pubnub_can_start_transaction(pubnub_t* pb);
404411

405412

406413
#endif /* defined INC_PUBNUB_COREAPI */

core/pubnub_coreapi_ex.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ struct pubnub_publish_options {
6262
};
6363

6464
/** This returns the default options for publish V1 transactions.
65-
Will set `store = true`, `cipher_key = NULL`, `replicate = true`
66-
and `meta = NULL`
65+
Will set `store = true`, `cipher_key = NULL`, `replicate = true`,
66+
`meta = NULL` and `method = pubnubPublishViaGet`
6767
*/
6868
struct pubnub_publish_options pubnub_publish_defopts(void);
6969

0 commit comments

Comments
 (0)