0

im trying to test a simple filewatcher in mac using the FSEvent Api. I get the callback with the events and everything seems to work but i can't recover the info contained in the info field of the context structure. Here is my code:

void feCallback(ConstFSEventStreamRef streamRef,
                   void* pClientCallBackInfo,
                   size_t numEvents,
                   void* pEventPaths,
                   const FSEventStreamEventFlags eventFlags[],
                   const FSEventStreamEventId eventIds[]);

Watcher::Watcher(const QString& pathToFolder) :
folderPath_(pathToFolder)
{
    CFStringCreateWithCString(kCFAllocatorDefault,path,kCFStringEncodingUTF8);
    NSString *directory = [[NSString stringWithUTF8String:folderPath_.toStdString().c_str()] stringByDeletingLastPathComponent];
    NSArray *pathToWatch = [NSArray arrayWithObjects:directory, nil];
    FSEventStreamContext context = {0, (void*)this, NULL, NULL, NULL}; //the second parameter is the 'user info' field

    CFAbsoluteTime latency = 3.0;
    FSEventStreamRef stream;
    stream = FSEventStreamCreate(NULL,
                             &feCallback,
                             &context,
                             (CFArrayRef)pathsToWatch,
                             kFSEventStreamEventIdSinceNow, 
                             latency,
                             kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer);
   if (!stream)
   {
       qDebug() << "Could not create event stream for path";
       return;
   }
   else
   {
       FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
       FSEventStreamStart(stream);
       qDebug() << "stream created";
   }
}

QString Watcher::getFolderPath()
{
    return folderPath_;
}

void  feCallback(ConstFSEventStreamRef streamRef,
                   void* pClientCallBackInfo,
                   size_t numEvents,
                   void* pEventPaths,
                   const FSEventStreamEventFlags eventFlags[],
                   const FSEventStreamEventId eventIds[])
{
    Q_UNUSED(streamRef)
    Q_UNUSED(eventIds)

    qDebug() << ((Watcher*)pClientCallBackInfo)->getFolderPath();
}

I get a sigsev error in the callback. Furthermore if i insert in the context just an int, for example:

int testInt = 4;
FSEventStreamContext context = {0, &testInt, NULL, NULL, NULL};

In the callback

qDebug() << *((int*)pClientCallBackInfo);

Prints me -1

So, what am i doing wrong? Thx in advance!

Sommerwild
  • 506
  • 1
  • 6
  • 18
  • 1
    Try logging the pointer value of `this` at the time you create the event stream and then the pointer value of `pClientCallBackInfo`. I suspect it's coming through just fine, but your problem is that the object or its `folderPath_` member are no longer valid. In your test with `testInt`, the problem is that the variable is on the stack. Once the constructor returns, that space is reused for other stuff and the address refers to junk (which happens to equal -1 in some cases). (By the way, what's the difference between `Watcher` and `MacWatcher`?) – Ken Thomases Jun 19 '15 at 04:01
  • The Macwatcher was a typo, thx for pointing it out. – Sommerwild Jun 19 '15 at 15:41
  • And you were right, the problem was in the 'Watcher' object, creation, not in the pointer. Thx again. – Sommerwild Jun 20 '15 at 01:10

1 Answers1

0

The problem was unrelated to this code. The pointer works fine but his object was lost.

Sommerwild
  • 506
  • 1
  • 6
  • 18