• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: FSMountServerVolumeAsync() in multiple threads?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FSMountServerVolumeAsync() in multiple threads?


  • Subject: Re: FSMountServerVolumeAsync() in multiple threads?
  • From: Jim Luther <email@hidden>
  • Date: Wed, 12 Aug 2009 11:47:41 -0700

On Aug 11, 2009, at 5:28 PM, Matt DeFoor wrote:

I have an application where I'm trying to mount multiple volumes in
their own thread using FSMountServerVolumeAsync(). The application is
Cocoa-based. So, I use:

[NSThread detachNewThreadSelector:@selector(mountResource:)
toTarget:self withObject:aResource]

to spawn each thread. The call to FSMountServerVolumeAsync() looks like this:

Result = FSMountServerVolumeAsync((CFURLRef)urlOfVolumeToMount, NULL,
(CFStringRef)[aResource username], (CFStringRef)[aResource password],
volumeOp, aResource, 0, mountUPP, CFRunLoopGetCurrent(),
CFSTR("MyMountMode"));

As you can tell, I'm using a callback. It handles certain aspects of
what is returned. When, I have only one thread, things work fine; the
callback is called and the volume is mounted. When I have more than
one volume to mount (ergo, more than one thread is calling
FSMountServerVolumeAsync()) varying results are produced. For example,
the return code from FSMountServerVolumeAsync() might be -50. Or there
might be an exception (EXC_BAD_ACCESS) in one of the functions that
FSMountServerVolumeAsync() calls (e.g. TAFPSession::AFPLogout).

Has anyone had success using FSMountServerVolumeAsync() in this manner?

Is there a better approach to FSMountServerVolumeAsync()'s usage?

Thanks,
Matt

P.S. Jim Luther suggest that I post here instead of the macnetworkprog list.

Matt,

I slapped together a quick tool that calls FSMountServerVolumeAsync() on multiple threads. I didn't find that FSMountServerVolumeAsync crashes or returns errors (well... it will return errors if there's really a problem).

I've pasted the source for my tool below (you'll have to change gMountInfos to the URLs you are using). Maybe it will help you figure out why your code doesn't work.

- Jim

#include <CoreServices/CoreServices.h>
#include <pthread.h>


struct MountInfo { const char *url; const char *user; const char *password; };

// array of server URLs to mount with usernames and passwords
const struct MountInfo gMountInfos[] = {
	{"afp://foo1.bar/volume", "user1", "password1"},
	{"afp://foo2.bar/volume", "user2", "password2"},
	{"afp://foo3.bar/volume", "user3", "password3"},
	{NULL, NULL, NULL}, // mark the end with NULLs
};



static void FSVolumeMountProc(FSVolumeOperation volumeOp, void *clientData, OSStatus err, FSVolumeRefNum mountedVolumeRefNum)
{
Boolean *inProgress = (Boolean *)clientData;

// all we're doing is setting inProgress (what clientData points to) to err so the tool can fall out of the wait loop.
*inProgress = FALSE;
}



static void DoMountServer(void *arg)
{
struct MountInfo *mountInfo;
pthread_t tid;
CFURLRef url = NULL;
CFStringRef user = NULL;
CFStringRef password = NULL;
OSStatus status;
FSVolumeMountUPP callback;
CFRunLoopRef runloop;
FSVolumeOperation volumeOp;
FSMountStatus mountStatus;
OSStatus volumeOpStatus;
FSVolumeRefNum mountedVolumeRefNum;
Boolean inProgress;

mountInfo = (struct MountInfo *)arg;
tid = pthread_self();
printf("[%p] mounting \'%s\', \'%s\', \'%s\'\n", tid, mountInfo->url, mountInfo->user, mountInfo->password);
fflush(stdout);

// create the CF objects from the c strings */
url = CFURLCreateWithBytes(kCFAllocatorDefault, (UInt8 *)mountInfo- >url, (CFIndex)strlen(mountInfo->url), kCFStringEncodingUTF8, NULL);
if ( url != NULL ) {
if ( strlen(mountInfo->user) ) {
user = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *) mountInfo->user, (CFIndex)strlen(mountInfo->user), kCFStringEncodingUTF8, FALSE);
}

if ( strlen(mountInfo->password) ) {
password = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *) mountInfo->password, (CFIndex)strlen(mountInfo->password), kCFStringEncodingUTF8, FALSE);
}

// create the callback UPP
callback = NewFSVolumeMountUPP(FSVolumeMountProc);

// get the current runloop to run on
runloop = CFRunLoopGetCurrent();

// create the volume operation
status = FSCreateVolumeOperation(&volumeOp);
if ( status == noErr ) {
// start the asynchronous mount
inProgress = TRUE; // set inProgress to "in progress"
status = FSMountServerVolumeAsync(url, NULL, user, password, volumeOp, (void *)&inProgress, kNilOptions, callback, runloop, kCFRunLoopDefaultMode);
if ( status == noErr ) {
// wait loop -- wait for inProgress to be FALSE
do
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5.0, true);
} while ( inProgress );

status = FSGetAsyncMountStatus(volumeOp, &mountStatus, &volumeOpStatus, &mountedVolumeRefNum, NULL);
if ( status == noErr ) {
printf("[%p] mountStatus = %d; volumeOpStatus = %d; mountedVolumeRefNum = %hd\n", tid, mountStatus, volumeOpStatus, mountedVolumeRefNum);
}
}
FSDisposeVolumeOperation(volumeOp);
}

if ( password != NULL ) {
CFRelease(password);
}
if ( user != NULL ) {
CFRelease(user);
}
CFRelease(url);
}
return;
}



int main (int argc, const char * argv[])
{
// make the threadID array big enough for all tids
pthread_t threadID[(sizeof(gMountInfos) / sizeof(struct MountInfo)) - 1];
int index;

index = 0;

// start a thread for each element in gMountInfos
while (gMountInfos[index].url != NULL) {
if ( pthread_create(&threadID[index], NULL, (void *)DoMountServer, (void *)&gMountInfos[index]) != 0 ) {
return ( EXIT_FAILURE );
}

++index;
}

// wait for all threads to complete
while ( index >= 0 ) {
pthread_join(threadID[index], NULL);
--index;
}
printf("done\n");

return ( EXIT_SUCCESS );
}


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: FSMountServerVolumeAsync() in multiple threads?
      • From: Matt DeFoor <email@hidden>
References: 
 >FSMountServerVolumeAsync() in multiple threads? (From: Matt DeFoor <email@hidden>)

  • Prev by Date: Re: FSMountServerVolumeAsync() in multiple threads?
  • Next by Date: Re: FSMountServerVolumeAsync() in multiple threads?
  • Previous by thread: Re: FSMountServerVolumeAsync() in multiple threads?
  • Next by thread: Re: FSMountServerVolumeAsync() in multiple threads?
  • Index(es):
    • Date
    • Thread