// compile with: g++ 1.cc -o test -Wall `pkg-config --cflags --libs glib-2.0` -lgthread-2.0
// or g++ 1.cc -o testq -lglib-2.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include/ -lgthread-2.0c
#include <glib.h>
#include <iostream>
#include <string.h>
int counter;
GAsyncQueue *q;
typedef struct MyStruct {
int foo;
char *data;
} *MyStructPtr;
gpointer looper(gpointer data) {
g_thread_init(NULL);
while (1) {
while (g_async_queue_length(q) > 0) {
MyStructPtr xtransport;
xtransport = new struct MyStruct;
xtransport = (MyStructPtr)g_async_queue_try_pop(q);
// The actual code is acting as weird, as if we have here, xtransport->data = last_text_value_ever_received;
std::cout << "str # " << xtransport->foo << ":" << xtransport->data << ":str\n";
}
}
}
void adder(char *data) {
char *processedData;
// someExternalAPICallToprocessData(data, &processeddata);
processedData = (char *)data;
MyStructPtr dtransport;
dtransport = new struct MyStruct;
dtransport->data = processedData;//processeddata;
dtransport->foo = ++counter;
g_async_queue_push(q, (gpointer*) dtransport);
}
int main() {
GThread *l;
g_thread_init(NULL);
q = g_async_queue_new();
l = g_thread_create(looper, NULL, FALSE, NULL);
sleep(2);
char *t;
t = strdupa("1111");
adder(t);
t = strdupa("222");
adder(t);
sleep (5);
}
Это рабочий лабораторный макет какого-то более крупного проекта.В проекте замечено странное поведение:
вместо main (), мы сидим в функции обратного вызова, которая получает некоторые данные из системного компонента.Пытаясь напечатать (например, cout) эти данные перед помещением в очереди, можно получить что-то вроде:
N1 (при обратном вызове): aaaabbbbcccc N2 (при обратном вызове): bbbbaaaacccc.
То же самое, если доступ к (вновь установленному указателю) dtransport-> data осуществляется в том же коде, в котором они были созданы (функция mainloop / callback) t;это нормально.
Но не могу получить правильное значение первых элементов в очереди!Поля данных всегда одинаковы - доступ к собранным данным через очередь, может получить только значение, которое было установлено в последнем обратном вызове;злой указатель, черт возьми, предполагается!
str # 1: bbbbaaaacccc.str # 2: bbbbaaaacccc.
Функция обратного вызова определяется как:
int someExternalAPICallToprocessData(...., unsigned char ** data);
Возвращает длину данных, а ** - возвращает указатель на указатель?Так что это проблема решения.
Вопрос в том, будет ли someExternalAPICallTOprocessData () заполнять и обрабатывать данные указателем на фиксированный адрес, хранящий только данные последнего вызова ?Как получить возвращаемую копию char * и безопасно поместить ее в MyStruct? Обратите внимание, что в следующей функции используются смещения ...
process(dequeued->data);
void process(char *data) {
my *ptr = NULL;
ptr = data + SOME_SIZE_CONST
...
}
И каким-то образом memcpy'ng содержимое processingData кажется segfault.so библиотека, которая содержит someExternalAPICallTOprocessData ().В контексте макета это конец adder ();в реальном контексте это конец функции обратного вызова для работы с сетью ядра;так смешно.