public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* problem with mmap and fork()
@ 2019-02-23  6:30 Glyn Gowing
  2019-02-23  9:30 ` Doug Henderson
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Glyn Gowing @ 2019-02-23  6:30 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 581 bytes --]

Hello everyone,

I have a program (attached) that works correctly on my mac but does
not work with Cygwin on Windows 10. I'm running the latest version of
Cygwin (downloaded the updates two days ago) and using gcc as the c
compiler.

What happens in the buggy execution is that the child obtains a lock
before the parent releases it. I'm using mmap and a pthread_mutex_t
object along with fork(). Again, this exact code works correctly on my
Mac running Mojave.

I've looked at the archives and online and I can't find any hints as
to what I may be doing incorrectly here

Thanks.

[-- Attachment #2: smtest2.c --]
[-- Type: text/plain, Size: 2919 bytes --]

// smtest2.c
//
// Dr. Glyn Gowing
// LeTourneau University
// COSC 4653 - Advanced Networks
//
// This program demonstrates how to use a lock with fork()ed processes by using
// shared memory.

#include <stdio.h>         // needed for printf
#include <sys/mman.h>      // needed for mmap
#include <unistd.h>        // needed for fork
#include <pthread.h>       // needed for the mutex and the mutexattr structs and functions


// this create_shared_memory function was found on stack exchange.
void* create_shared_memory(size_t size) 
{
   // Our memory buffer will be readable and writable:
   int protection = PROT_READ | PROT_WRITE;
   
   // The buffer will be shared (meaning other processes can access it), but
   // anonymous (meaning third-party processes cannot obtain an address for it),
   // so only this process and its children will be able to use it:
   int visibility = MAP_ANONYMOUS | MAP_SHARED;
   
   // The remaining parameters to `mmap()` are not important for this use case,
   // but the manpage for `mmap` explains their purpose.
   return mmap(NULL, size, protection, visibility, 0, 0);
}
// end borrowed code


int main() 
{
   // create mutex and mutexattr structs so we can create the mutex
   // these are created as shared memory so they can be accessed by both processes
   pthread_mutex_t *lock = (pthread_mutex_t *)create_shared_memory(sizeof(pthread_mutex_t));
   pthread_mutexattr_t *attr = (pthread_mutexattr_t *)create_shared_memory(sizeof(pthread_mutexattr_t));
   
   // initialize the mutexattr struct
   pthread_mutexattr_init(attr);
   // set it so it can be shared between processes
   // without this, the child will not be able to acquire the lock even if it is
   // in shared memory.
   pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);

   // initialize the mutex itself, using the attributes we just created
   pthread_mutex_init(lock, attr);
  
   // fork()
   int pid = fork();

   if (pid == 0)  // child
   {
      printf("Child sleeping 5\n");
      // sleep 5 seconds to give parent a chance to acquire lock
      sleep(5);
      // try to acquire lock. This will block until lock is acquired
      pthread_mutex_lock(lock);
      printf("child: acquired lock - Sleeping 3 seconds\n");
      sleep(3);
      // release lock after acquiring it
      pthread_mutex_unlock(lock);
      printf("child: unlocked.\n");
   } 
   else  // parent
   {
      // acquire lock immediately to force child to block
      pthread_mutex_lock(lock);
      printf("parent: acquired lock - Sleeping 10 seconds\n");
      sleep(10);
      // release lock to give child a chance
      pthread_mutex_unlock(lock);
      printf("parent: unlocked. Sleeping 5 to let child catch up.\n");
      sleep(5);
   }
   
   // mmap'ed memory is automatically unmapped when the process ends.
   return 0;
}

[-- Attachment #3: Type: text/plain, Size: 219 bytes --]


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23  6:30 problem with mmap and fork() Glyn Gowing
@ 2019-02-23  9:30 ` Doug Henderson
  2019-02-23 12:54 ` Václav Haisman
  2019-02-23 16:05 ` Doug Henderson
  2 siblings, 0 replies; 8+ messages in thread
From: Doug Henderson @ 2019-02-23  9:30 UTC (permalink / raw)
  To: cygwin

On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> I have a program (attached) that works correctly on my mac but does
> not work with Cygwin on Windows 10. I'm running the latest version of

> What happens in the buggy execution is that the child obtains a lock
> before the parent releases it. I'm using mmap and a pthread_mutex_t
> object along with fork(). Again, this exact code works correctly on my
> Mac running Mojave.

The problem is not with mmap() and fork(). The problem is with using
both fork() and pthread_mutex_*().

In Linux, and cygwin, the pthread_mutex appears to be a pointer to a
queue (maybe) located in writable (or copy-on-write) memory which
seems not to be shared between processes. This memory is common to all
pthreads (in each process), so pthread_mutex's will work for them, but
pthreads in another process will be using a different mutex.

Darwin (the mac's OS) is derived from NeXTSTEP, BSD, Mach, and other
free software projects, so it's implementation of pthreads may be
vastly or subtly different than the Linux and cygwin version,
resulting in different behaviour.

The "pthread_mutex_t" you create in shared memory, is just a pointer
(think a HANDLE) to the actual mutex data structure. I think you would
see identical results if the mutex was created in non-shared memory.

Search for "fork and pthread" on e.g. Google, to see some info about
mixing these features, and about the recommendations to use semaphores
for creating critical sections between processes vs using mutexes
between pthreads.

HTH
Doug
-- 
Doug Henderson, Calgary, Alberta, Canada - from gmail.com

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23  6:30 problem with mmap and fork() Glyn Gowing
  2019-02-23  9:30 ` Doug Henderson
@ 2019-02-23 12:54 ` Václav Haisman
  2019-02-23 16:05 ` Doug Henderson
  2 siblings, 0 replies; 8+ messages in thread
From: Václav Haisman @ 2019-02-23 12:54 UTC (permalink / raw)
  To: cygwin


[-- Attachment #1.1: Type: text/plain, Size: 962 bytes --]

On 23. 02. 19 1:02, Glyn Gowing wrote:
> Hello everyone,
> 
> I have a program (attached) that works correctly on my mac but does
> not work with Cygwin on Windows 10. I'm running the latest version of
> Cygwin (downloaded the updates two days ago) and using gcc as the c
> compiler.
> 
> What happens in the buggy execution is that the child obtains a lock
> before the parent releases it. I'm using mmap and a pthread_mutex_t
> object along with fork(). Again, this exact code works correctly on my
> Mac running Mojave.
> 
> I've looked at the archives and online and I can't find any hints as
> to what I may be doing incorrectly here
> 

You cannot fork() and keep using threading primitives in the child. The
child has only one thread and the mutexes are usually in a state that
can be inconsistent. Basically, the only safe thing to do in
multithreaded process after fork is to exec() and reinitialize your
application.

-- 
VH


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23  6:30 problem with mmap and fork() Glyn Gowing
  2019-02-23  9:30 ` Doug Henderson
  2019-02-23 12:54 ` Václav Haisman
@ 2019-02-23 16:05 ` Doug Henderson
  2019-02-23 22:11   ` Glyn Gowing
                     ` (2 more replies)
  2 siblings, 3 replies; 8+ messages in thread
From: Doug Henderson @ 2019-02-23 16:05 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1119 bytes --]

On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> I have a program (attached) that works correctly on my mac but does
> not work with Cygwin on Windows 10. I'm running the latest version of

> What happens in the buggy execution is that the child obtains a lock
> before the parent releases it. I'm using mmap and a pthread_mutex_t
> object along with fork(). Again, this exact code works correctly on my
> Mac running Mojave.

On further analysis, the call to
> pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
is failing. The error is EINVAL (22) Invalid argument.

This suggests that pthread mutexes cannot be shared between processes
by using shared memory in cygwin. I have not attempted to determine if
this is working as expected, or if this is a bug, or a limitation in
the Windows environment.

I have attached my files:
smtest2.c - my heavily modified version of OP's original.
smtest2.txt - output from running this version.showing error.
smtest3.c - my version which uses 2 pthreads in a single process
smtest3.txt - output from running this version, showing OP's expected results.

HTH
Doug

[-- Attachment #2: smtest2.txt --]
[-- Type: text/plain, Size: 178 bytes --]

gcc -std=c11 -pthread -Wall -Wextra -Werror -o smtest2 smtest2.c && ./smtest2
22 Invalid argument
pthread_mutexattr_setpshared: No error
make: *** [Makefile:30: smtest2] Error 1

[-- Attachment #3: smtest3.c --]
[-- Type: application/octet-stream, Size: 5570 bytes --]

// smtest2.c
//
// Dr. Glyn Gowing
// LeTourneau University
// COSC 4653 - Advanced Networks
//
// This program demonstrates how to use a lock with fork()ed processes by using
// shared memory.
//
// heavily modified by Doug Henderson

#include <stdio.h>         // needed for printf
#include <stdlib.h>         // needed for exit
#include <string.h>         // needed for strerror
#include <time.h>          // needed for time
#include <sys/mman.h>      // needed for mmap
#include <unistd.h>        // needed for fork
#include <pthread.h>       // needed for the mutex and the mutexattr structs and functions


// this create_shared_memory function was found on stack exchange.
void* create_shared_memory(size_t size)
{
	// Our memory buffer will be readable and writable:
	int protection = PROT_READ | PROT_WRITE;

	// The buffer will be shared (meaning other processes can access it), but
	// anonymous (meaning third-party processes cannot obtain an address for it),
	// so only this process and its children will be able to use it:
	int visibility = MAP_ANONYMOUS | MAP_SHARED;

	// The remaining parameters to `mmap()` are not important for this use case,
	// but the manpage for `mmap` explains their purpose.
	return mmap(NULL, size, protection, visibility, 0, 0);
}
// end borrowed code

void *child_routine(void *_lock)
{
	pthread_mutex_t *lock = (pthread_mutex_t *)_lock;
	int err;

	printf("%ld - Child : checking  lock (%11p) - Before sleeping 5 seconds.\n", time(NULL), (void *)(*lock));
	// sleep 5 seconds to give parent a chance to acquire lock
	sleep(5);
	// try to acquire lock. This will block until lock is acquired
	printf("%ld - Child : acquiring lock (%11p) - After  sleeping 5 seconds.\n", time(NULL), (void *)(*lock));
	err = pthread_mutex_lock(lock);
	if (err != 0) {
		printf("%ld - Child : pthread_mutex_lock error: %d %s\n", time(NULL), err, strerror(err));
		exit(err);
	}

	printf("%ld - Child : acquired  lock (%11p) - Before sleeping 3 seconds.\n", time(NULL), (void *)(*lock));
	sleep(3);
	// release lock after acquiring it
	printf("%ld - Child : unlocking lock (%11p) - After sleeping 3 seconds.\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_unlock(lock);
	if (err != 0) {
		printf("%ld - Child : pthread_mutex_unlock error: %d %s\n", time(NULL), err, strerror(err));
		exit(err);
	}

	printf("%ld - Child : unlocked  lock (%11p).\n", time(NULL), (void *)(* lock));
	return (void*)NULL;
}

void *parent_routine(void *_lock)
{
	pthread_mutex_t *lock = (pthread_mutex_t *)_lock;
	int err;

	// acquire lock immediately to force child to block
	printf("%ld - Parent: acquiring lock (%11p)\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_lock(lock);
	if (err != 0) {
		printf("%ld - Parent: pthread_mutex_lock error: %d %s\n", time(NULL), err, strerror(err));
		exit(err);
	}

	printf("%ld - Parent: acquired  lock (%11p) - Before sleeping 10 seconds.\n", time(NULL), (void *)(* lock));
	sleep(10);
	// release lock to give child a chance
	printf("%ld - Parent: unlocking lock (%11p) - After sleeping 10 seconds.\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_unlock(lock);
	if (err != 0) {
		printf("%ld - Parent: pthread_mutex_unlock error: %d %s\n", time(NULL), err, strerror(err));
		exit(err);
	}

	printf("%ld - Parent: unlocked  lock (%11p) - Before sleeping 5 seconds to let child catch up.\n", time(NULL), (void *)(* lock));
	sleep(5);
	printf("%ld -                                      - After  sleeping 5 seconds to let child catch up.\n", time(NULL));
	return (void*)NULL;
}

int main()
{
	int err;

	// create mutex and mutexattr structs so we can create the mutex
	// these are created as shared memory so they can be accessed by both processes
	pthread_mutex_t *lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
	pthread_mutexattr_t *attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));

	// initialize the mutexattr struct
	err = pthread_mutexattr_init(attr);
	if (err) {
		perror("pthread_mutexattr_init");
		exit(EXIT_FAILURE);
	}

	//// set it so it can be shared between processes
	//// without this, the child will not be able to acquire the lock even if it is
	//// in shared memory.
	//err = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
	//if (err) {
		//fprintf(stderr, "%d %s\n", err, strerror(err));
		//perror("pthread_mutexattr_setpshared");
		//exit(EXIT_FAILURE);
	//}

	// initialize the mutex itself, using the attributes we just created
	err = pthread_mutex_init(lock, attr);
	if (err) {
		printf("%ld - both: pthread_mutex_init error: %d %s\n", time(NULL), err, strerror(err));
		exit(err);
	 }
	printf("%ld - both  : attr, lock, lock->next: %11p %11p %11p\n", time(NULL), (void *)attr, (void *)lock, (void *)(*lock));

	pthread_t child_thread, parent_thread;

	err = pthread_create(&child_thread, NULL, (void *)&child_routine, (void *) lock);
	if (err) {
		perror("pthread_create child");
		exit(EXIT_FAILURE);
	}
	err = pthread_create(&parent_thread, NULL, (void *)&parent_routine, (void *) lock);
	if (err) {
		perror("pthread_create parent");
		exit(EXIT_FAILURE);
	}

	err = pthread_join( child_thread, NULL);
	if (err) {
		perror("pthread_join child");
		exit(EXIT_FAILURE);
	}
	err = pthread_join( parent_thread, NULL);
	if (err) {
		perror("pthread_join parent");
		exit(EXIT_FAILURE);
	}

	// mmap'ed memory is automatically unmapped when the process ends.
	return 0;
}

[-- Attachment #4: smtest3.txt --]
[-- Type: text/plain, Size: 936 bytes --]

gcc -std=c11 -pthread -Wall -Wextra -Werror -o smtest3 smtest3.c && ./smtest3
1550925866 - both  : attr, lock, lock->next: 0x600000430 0x600000410 0x600000470
1550925866 - Child : checking  lock (0x600000470) - Before sleeping 5 seconds.
1550925866 - Parent: acquiring lock (0x600000470)
1550925866 - Parent: acquired  lock (0x600000470) - Before sleeping 10 seconds.
1550925871 - Child : acquiring lock (0x600000470) - After  sleeping 5 seconds.
1550925876 - Parent: unlocking lock (0x600000470) - After sleeping 10 seconds.
1550925876 - Parent: unlocked  lock (0x600000470) - Before sleeping 5 seconds to let child catch up.
1550925876 - Child : acquired  lock (0x600000470) - Before sleeping 3 seconds.
1550925879 - Child : unlocking lock (0x600000470) - After sleeping 3 seconds.
1550925879 - Child : unlocked  lock (0x600000470).
1550925881 -                                      - After  sleeping 5 seconds to let child catch up.

[-- Attachment #5: smtest2.c --]
[-- Type: application/octet-stream, Size: 5150 bytes --]

// smtest2.c
//
// Dr. Glyn Gowing
// LeTourneau University
// COSC 4653 - Advanced Networks
//
// This program demonstrates how to use a lock with fork()ed processes by using
// shared memory.

#include <stdio.h>         // needed for printf
#include <stdlib.h>         // needed for exit // djh
#include <string.h>         // needed for strerror // djh
#include <time.h>          // needed for time // djh
#include <sys/mman.h>      // needed for mmap
#include <unistd.h>        // needed for fork
#include <pthread.h>       // needed for the mutex and the mutexattr structs and functions


// this create_shared_memory function was found on stack exchange.
void* create_shared_memory(size_t size)
{
	// Our memory buffer will be readable and writable:
	int protection = PROT_READ | PROT_WRITE;

	// The buffer will be shared (meaning other processes can access it), but
	// anonymous (meaning third-party processes cannot obtain an address for it),
	// so only this process and its children will be able to use it:
	int visibility = MAP_ANONYMOUS | MAP_SHARED;

	// The remaining parameters to `mmap()` are not important for this use case,
	// but the manpage for `mmap` explains their purpose.
	return mmap(NULL, size, protection, visibility, 0, 0);
}
// end borrowed code

void *child_routine(void *_lock)
{
	pthread_mutex_t *lock = (pthread_mutex_t *)_lock;
	int err; // djh
	printf("%ld - Child : checking  lock (%11p) - Before sleeping 5 seconds.\n", time(NULL), (void *)(*lock));
	// sleep 5 seconds to give parent a chance to acquire lock
	sleep(5);
	// try to acquire lock. This will block until lock is acquired
	printf("%ld - Child : acquiring lock (%11p) - After  sleeping 5 seconds.\n", time(NULL), (void *)(*lock));
	err = pthread_mutex_lock(lock);
	if (err != 0) {
		printf("%ld - Child : pthread_mutex_lock error: %d %s\n", time(NULL), err, strerror(err)); // djh
		exit(err);
	}
	printf("%ld - Child : acquired  lock (%11p) - Before sleeping 3 seconds.\n", time(NULL), (void *)(*lock));
	sleep(3);
	// release lock after acquiring it
	printf("%ld - Child : unlocking lock (%11p) - After sleeping 3 seconds.\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_unlock(lock);
	if (err != 0) {
		printf("%ld - Child : pthread_mutex_unlock error: %d %s\n", time(NULL), err, strerror(err)); // djh
		exit(err);
	}
	printf("%ld - Child : unlocked  lock (%11p).\n", time(NULL), (void *)(* lock));
	return (void*)NULL;
}

void *parent_routine(void *_lock)
{
	pthread_mutex_t *lock = (pthread_mutex_t *)_lock;
	int err; // djh
	// acquire lock immediately to force child to block
	printf("%ld - Parent: acquiring lock (%11p)\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_lock(lock);
	if (err != 0) {
		printf("%ld - Parent: pthread_mutex_lock error: %d %s\n", time(NULL), err, strerror(err)); // djh
		exit(err);
	}
	printf("%ld - Parent: acquired  lock (%11p) - Before sleeping 10 seconds.\n", time(NULL), (void *)(* lock));
	sleep(10);
	// release lock to give child a chance
	printf("%ld - Parent: unlocking lock (%11p) - After sleeping 10 seconds.\n", time(NULL), (void *)(* lock));
	err = pthread_mutex_unlock(lock);
	if (err != 0) {
		printf("%ld - Parent: pthread_mutex_unlock error: %d %s\n", time(NULL), err, strerror(err)); // djh
		exit(err);
	}
	printf("%ld - Parent: unlocked  lock (%11p) - Before sleeping 5 seconds to let child catch up.\n", time(NULL), (void *)(* lock));
	sleep(5);
	printf("%ld -                                      - After  sleeping 5 seconds to let child catch up.\n", time(NULL));
	return (void*)NULL;
}

int main()
{
	int err;

	// create mutex and mutexattr structs so we can create the mutex
	// these are created as shared memory so they can be accessed by both processes
	pthread_mutex_t *lock = (pthread_mutex_t *)create_shared_memory(sizeof(pthread_mutex_t));
	pthread_mutexattr_t *attr = (pthread_mutexattr_t *)create_shared_memory(sizeof(pthread_mutexattr_t));

	// initialize the mutexattr struct
	err = pthread_mutexattr_init(attr);
	if (err) {
		perror("pthread_mutexattr_init");
		exit(EXIT_FAILURE);
	}

	// set it so it can be shared between processes
	// without this, the child will not be able to acquire the lock even if it is
	// in shared memory.
	err = pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
	if (err) {
		fprintf(stderr, "%d %s\n", err, strerror(err));
		perror("pthread_mutexattr_setpshared");
		exit(EXIT_FAILURE);
	}

	// initialize the mutex itself, using the attributes we just created
	err = pthread_mutex_init(lock, attr);
	if (err != 0) {
		printf("%ld - both: pthread_mutex_init error: %d %s\n", time(NULL), err, strerror(err)); // djh
		exit(err);
	 }
	printf("%ld - both  : attr, lock, lock->next: %11p %11p %11p\n", time(NULL), (void *)attr, (void *)lock, (void *)(*lock)); // djh

	// fork()
	int pid = fork();

	if (pid == 0)  // child
	{
		child_routine(lock);
	}
	else  // parent
	{
		parent_routine(lock);
	}

	// mmap'ed memory is automatically unmapped when the process ends.
	return 0;
}

[-- Attachment #6: Type: text/plain, Size: 219 bytes --]


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23 16:05 ` Doug Henderson
@ 2019-02-23 22:11   ` Glyn Gowing
  2019-02-25 10:03   ` Houder
  2019-02-25 12:26   ` Houder
  2 siblings, 0 replies; 8+ messages in thread
From: Glyn Gowing @ 2019-02-23 22:11 UTC (permalink / raw)
  To: cygwin

Thanks for confirming for me that cygwin can't do this with fork().

I guess I'll have to warn them about this difference in cygwin. I was
hoping I had made a mistake somewhere.

On Sat, Feb 23, 2019 at 6:54 AM Doug Henderson <djndnbvg@gmail.com> wrote:
>
> On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> > I have a program (attached) that works correctly on my mac but does
> > not work with Cygwin on Windows 10. I'm running the latest version of
>
> > What happens in the buggy execution is that the child obtains a lock
> > before the parent releases it. I'm using mmap and a pthread_mutex_t
> > object along with fork(). Again, this exact code works correctly on my
> > Mac running Mojave.
>
> On further analysis, the call to
> > pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
> is failing. The error is EINVAL (22) Invalid argument.
>
> This suggests that pthread mutexes cannot be shared between processes
> by using shared memory in cygwin. I have not attempted to determine if
> this is working as expected, or if this is a bug, or a limitation in
> the Windows environment.
>
> I have attached my files:
> smtest2.c - my heavily modified version of OP's original.
> smtest2.txt - output from running this version.showing error.
> smtest3.c - my version which uses 2 pthreads in a single process
> smtest3.txt - output from running this version, showing OP's expected results.
>
> HTH
> Doug
>
> --
> Problem reports:       http://cygwin.com/problems.html
> FAQ:                   http://cygwin.com/faq/
> Documentation:         http://cygwin.com/docs.html
> Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23 16:05 ` Doug Henderson
  2019-02-23 22:11   ` Glyn Gowing
@ 2019-02-25 10:03   ` Houder
  2019-02-25 12:26   ` Houder
  2 siblings, 0 replies; 8+ messages in thread
From: Houder @ 2019-02-25 10:03 UTC (permalink / raw)
  To: cygwin

On Sat, 23 Feb 2019 05:54:18, Doug Henderson  wrote:

> On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> > I have a program (attached) that works correctly on my mac but does
> > not work with Cygwin on Windows 10. I'm running the latest version of
[snip]

> On further analysis, the call to
> > pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
> is failing. The error is EINVAL (22) Invalid argument.
> 
> This suggests that pthread mutexes cannot be shared between processes
> by using shared memory in cygwin. I have not attempted to determine if
> this is working as expected, or if this is a bug, or a limitation in
> the Windows environment.

For the record, the output on Linux (FC28):

@@ ./Dsmtest2 (Doug's version of the original smtest2.c)
1551022585 - both  : attr, lock, lock->next: 0x7f4ec2ceb000 0x7f4ec2cec000 0x7f4ec2cec000
1551022585 - Parent: acquiring lock (0x7f4ec2cec000)
1551022585 - Parent: acquired  lock (0x7f4ec2cec000) - Before sleeping 10 seconds.
1551022585 - Child : checking  lock (0x7f4ec2cec000) - Before sleeping 5 seconds.
1551022590 - Child : acquiring lock (0x7f4ec2cec000) - After  sleeping 5 seconds.
1551022595 - Parent: unlocking lock (0x7f4ec2cec000) - After  sleeping 10 seconds.
1551022595 - Parent: unlocked  lock (0x7f4ec2cec000) - Before sleeping 5 seconds to let child catch up.
1551022595 - Child : acquired  lock (0x7f4ec2cec000) - Before sleeping 3 seconds.
1551022598 - Child : unlocking lock (0x7f4ec2cec000) - After  sleeping 3 seconds.
1551022598 - Child : unlocked  lock (0x7f4ec2cec000).
1551022600 -                                         - After  sleeping 5 seconds to let child catch up.
@@ 

... as I understand it, this is between a parent thread and a child thread,
after fork(), -- and only these two! -- using mutexes in shared memory, that
is, shared memory between the two processes (parent and child) ...

Logically, I would say, the same as 2 threads in one process ...

(and yes, in general, all threads are "dead" after fork(), except for the
 thread that is the child of the calling thread).

Henri


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-23 16:05 ` Doug Henderson
  2019-02-23 22:11   ` Glyn Gowing
  2019-02-25 10:03   ` Houder
@ 2019-02-25 12:26   ` Houder
  2019-02-25 12:43     ` Corinna Vinschen
  2 siblings, 1 reply; 8+ messages in thread
From: Houder @ 2019-02-25 12:26 UTC (permalink / raw)
  To: cygwin

On Sat, 23 Feb 2019 05:54:18, Doug Henderson  wrote:

> On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> > I have a program (attached) that works correctly on my mac but does
> > not work with Cygwin on Windows 10. I'm running the latest version of
[snip]

> On further analysis, the call to
> > pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
> is failing. The error is EINVAL (22) Invalid argument.
> 
> This suggests that pthread mutexes cannot be shared between processes
> by using shared memory in cygwin. I have not attempted to determine if
> this is working as expected, or if this is a bug, or a limitation in
> the Windows environment.

For the record, this (i.c. PTHREAD_PROCESS_SHARED) is not yet supported on
Cygwin.

winsup/cygwin/thread.cc

3636 extern "C" int
3637 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3638 {
3639   if (!pthread_mutexattr::is_good_object (attr))
3640     return EINVAL;
3641   /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3642    *functionality
3643    */
3644   if (pshared != PTHREAD_PROCESS_PRIVATE)
3645     return EINVAL; <====
3646   (*attr)->pshared = pshared;
3647   return 0;
3648 }

Henri


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: problem with mmap and fork()
  2019-02-25 12:26   ` Houder
@ 2019-02-25 12:43     ` Corinna Vinschen
  0 siblings, 0 replies; 8+ messages in thread
From: Corinna Vinschen @ 2019-02-25 12:43 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1478 bytes --]

On Feb 25 11:51, Houder wrote:
> On Sat, 23 Feb 2019 05:54:18, Doug Henderson  wrote:
> 
> > On Fri, 22 Feb 2019 at 17:01, Glyn Gowing <> wrote:
> > > I have a program (attached) that works correctly on my mac but does
> > > not work with Cygwin on Windows 10. I'm running the latest version of
> [snip]
> 
> > On further analysis, the call to
> > > pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
> > is failing. The error is EINVAL (22) Invalid argument.
> > 
> > This suggests that pthread mutexes cannot be shared between processes
> > by using shared memory in cygwin. I have not attempted to determine if
> > this is working as expected, or if this is a bug, or a limitation in
> > the Windows environment.
> 
> For the record, this (i.c. PTHREAD_PROCESS_SHARED) is not yet supported on
> Cygwin.
> 
> winsup/cygwin/thread.cc
> 
> 3636 extern "C" int
> 3637 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
> 3638 {
> 3639   if (!pthread_mutexattr::is_good_object (attr))
> 3640     return EINVAL;
> 3641   /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
> 3642    *functionality
> 3643    */
> 3644   if (pshared != PTHREAD_PROCESS_PRIVATE)
> 3645     return EINVAL; <====
> 3646   (*attr)->pshared = pshared;
> 3647   return 0;
> 3648 }
> 
> Henri

Needless to say that patches in this area are welcome, I guess.


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-02-25 12:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-23  6:30 problem with mmap and fork() Glyn Gowing
2019-02-23  9:30 ` Doug Henderson
2019-02-23 12:54 ` Václav Haisman
2019-02-23 16:05 ` Doug Henderson
2019-02-23 22:11   ` Glyn Gowing
2019-02-25 10:03   ` Houder
2019-02-25 12:26   ` Houder
2019-02-25 12:43     ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).