Results 1 to 4 of 4
Hi all;
I have a program called "Device Manager" to manange usb tokens for sending and recieving
multiple data to/from them using shared memory method.
Here is a piece of ...
- 10-23-2010 #1Just Joined!
- Join Date
- Sep 2009
- Posts
- 27
Problem with a MultiThreaded program in C++?
Hi all;
I have a program called "Device Manager" to manange usb tokens for sending and recieving
multiple data to/from them using shared memory method.
Here is a piece of "Device Manager" code:
The type "MY_ReqHandler" is a C++ class that it's constructor initializes a token connected to the system as below:Code:int main() { pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; MY_ReqHandler *reqHandler = new MY_ReqHandler(&lock); MY_SharedMemory shMem; if(shMem.init()) retlog((char*)"main", 1, 1); printf("sharedMem inited\n"); int ret = shMem.create(); printf("sharedMem create retVal %d\n", ret); ... }
And the Thread function as below:Code:MY_ReqHandler::MY_ReqHandler (pthread_mutex_t* trdlock) { enterLogger ((char*)"MY_ReqHandler::MY_ReqHandler"); this->lock = trdlock; int ret = pthread_create(&hThread, NULL, run, (void*) this); if (ret) perror("pthread_create failed."); returnLogger((char*)"MY_ReqHandler::MY_ReqHandler", 0, 0); return; }
Here, "MY_USBWrapper" type is another class that one of it's member functions called "InitToken" initializes the token (including find and get a handle to it using "libusb" library inside a function with name "rawhid_open").Code:void* run (void* obj) { enterLogger ((char*)"run (MY_ReqHandler)"); pthread_mutex_lock(((MY_ReqHandler*)obj)->lock); ((MY_USBWrapper*)obj)->InitToken(1, VENDORID, PRODUCTID); pthread_mutex_unlock(((MY_ReqHandler*)obj)->lock); retlog((char*)"run (MY_ReqHandler)", 0, 0); }
The function "rawhid_open" that is called in "InitToken" is as below (It uses "libusb" library functions):
Also, "MY_SharedMemory" class is intended for shared memory (IPC) operations and the member function "init" is as following:Code:int rawhid_open(int max, int vid, int pid) { struct usb_bus *bus; struct usb_device *dev; struct usb_interface *iface; struct usb_interface_descriptor *desc; struct usb_endpoint_descriptor *ep; usb_dev_handle *u; uint8_t buf[1024]; int i, n, ep_in, ep_out, count=0, claimed; hid_t *hid; if(first_hid) free_all_hid(); printf("rawhid_open, max=%d\n", max); if(max < 1) return 0; usb_init(); usb_find_busses(); printf("usb_find_busses is called\n"); usb_find_devices(); printf("usb_find_devices is called\n"); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (vid > 0 && dev->descriptor.idVendor != vid) continue; if (pid > 0 && dev->descriptor.idProduct != pid) continue; if (!dev->config) continue; if (dev->config->bNumInterfaces < 1) continue; printf("device: vid=%04X, pid=%04X, with %d iface\n", dev->descriptor.idVendor, dev->descriptor.idProduct, dev->config->bNumInterfaces); iface = dev->config->interface; u = NULL; claimed = 0; for(i=0; i<dev->config->bNumInterfaces && iface; i++, iface++) { desc = iface->altsetting; if (!desc) continue; printf(" type %d, %d, %d\n", desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol); if (desc->bInterfaceClass != 3) continue; if (desc->bInterfaceSubClass != 0) continue; if (desc->bInterfaceProtocol != 0) continue; ep = desc->endpoint; ep_in = ep_out = 0; for (n = 0; n < desc->bNumEndpoints; n++, ep++) { if (ep->bEndpointAddress & 0x80) { if (!ep_in) ep_in = ep->bEndpointAddress & 0x7F; printf(" IN endpoint %d\n", ep_in); } else { if (!ep_out) ep_out = ep->bEndpointAddress; printf(" OUT endpoint %d\n", ep_out); } } if (!ep_in) continue; if (!u) { u = usb_open(dev); if (!u) { printf(" unable to open device\n"); break; } } printf(" hid interface (generic)\n"); if (usb_get_driver_np(u, i, (char *)buf, sizeof(buf)) >= 0) { printf(" in use by driver \"%s\"\n", buf); if (usb_detach_kernel_driver_np(u, i) < 0) { printf(" unable to detach from kernel\n"); continue; } } if (usb_claim_interface(u, i) < 0) { printf(" unable claim interface %d\n", i); continue; } hid = (struct hid_struct *)malloc(sizeof(struct hid_struct)); if (!hid) { usb_release_interface(u, i); continue; } hid->usb = u; hid->ep_in = ep_in; hid->ep_out = ep_out; hid->open = 1; add_hid(hid); claimed++; count++; if (count >= max) return count; } if (u && !claimed) usb_close(u); } } return count; }
But when I run the "Device Manager" executable file, I see the following result:Code:MY_SharedMemory::init () { fprintf(stderr, "All numeric input is expected to follow C conventions:\n"); fprintf(stderr, "\t0x... is interpreted as hexadecimal,\n"); fprintf(stderr, "\t0... is interpreted as octal,\n"); fprintf(stderr, "\totherwise, decimal.\n"); /* Get the key. */ fprintf(stderr, "Enter key: "); scanf("%li", (long int*) &key); /* Get the size of the segment. */ fprintf(stderr, "Enter size: "); scanf("%i", &size); /* Get the shmflg value. */ fprintf(stderr, "Expected flags for the shmflg argument are:\n"); fprintf(stderr, "\tIPC_CREAT = \t%#8.8o\n", IPC_CREAT); fprintf(stderr, "\tIPC_EXCL = \t%#8.8o\n", IPC_EXCL); fprintf(stderr, "\towner read =\t%#8.8o\n", 0400); fprintf(stderr, "\towner write =\t%#8.8o\n", 0200); fprintf(stderr, "\tgroup read =\t%#8.8o\n", 040); fprintf(stderr, "\tgroup write =\t%#8.8o\n", 020); fprintf(stderr, "\tother read =\t%#8.8o\n", 04); fprintf(stderr, "\tother write =\t%#8.8o\n", 02); fprintf(stderr, "Enter shmflg: "); scanf("%i", &shmflg); turn = 2; return 0; }
As you see, in the middle of "rawhid_open" function (that is, after "usb_find_busses is called" message), the program switches to "Sharememory::init" function. I mean, the control of programCode:rawhid_open, max=1 usb_find_busses is called All numeric input is expected to follow C conventions: 0x... is interpreted as hexadecimal, 0... is interpreted as octal, otherwise, decimal. Enter key: usb_find_devices is called device: vid=E854, pid=1230, with 1 iface type 3, 0, 0 IN endpoint 1 OUT endpoint 2 hid interface (generic) in use by driver "usbfs" found rawhid device 10 Enter size: 10 Expected flags for the shmflg argument are: IPC_CREAT = 00001000 IPC_EXCL = 00002000 owner read = 00000400 owner write = 00000200 group read = 00000040 group write = 00000020 other read = 00000004 other write = 00000002 Enter shmflg: 00001000 sharedMem inited sharedMem create retVal 0 sharedMem created
exits from "rawhid_open" function or thread function of "MY_ReqHandler" constructor and the constructor returns.
So that, the control goes to the rest of "Device manager" code at "shMem.init" part in:
And again, in the "Enter key:" part, switches to the rest of "MY_ReqHandler" constructor orCode:All numeric input is expected to follow C conventions: ...
"rawhid_open" function at "usb_find_devices is called" and ...
My question is that why do I face this result?!
I expect that at first, the "MY_ReqHandler" constructor or thread function runs completely (token to be initialized)and then "shMem.init" to be run!
But I see the mentioned result!!
Could you help me what the problem is?
Unfortunately, I couldn't find the solution. help me please...
TIA.
- 10-23-2010 #2Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Be patient. It will take awhile for me (or other folks) to find the time to analyze your code.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 10-23-2010 #3Just Joined!
- Join Date
- Sep 2009
- Posts
- 27
- 10-25-2010 #4Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Flush the output before you execute the scanf() functions. IE, fflush(stdout) to be sure that what you are seeing is what is really happening. Also, please provide the class definitions (headers) for MY_SharedMemory and MY_ReqHandler along with the code for their constructors.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!


Reply With Quote
