| View previous topic :: View next topic |
| Author |
Message |
AudioMonster
Joined: 07 Sep 2005 Posts: 37
|
Posted: Mon Sep 26, 2005 6:23 pm Post subject: Receiving UDP data thru socket in its own thread |
|
|
Hello,
I'm trying to receive some data sent by my PC UDP client over WiFi.
I would like to receive them in a separate thread :
bool PspUDPrx::StartListening()
{
sceNetInetBind( _socketRX, (struct sockaddr* )&_addr, sizeof(_addr));
int tmp = sceKernelCreateThread("PspUDPrx",PspUDPrx::UdpRxThread, 0x18, 0x10000, 0, 0);
if(tmp >= 0)
{
sceKernelStartThread(tmp, sizeof(PspUDPrx*), this);
}
else
return false;
// ListenInOwnThread();
return true;
}
// ----------------------------------------------------------------------------
//
// ----------------------------------------------------------------------------
int PspUDPrx::UdpRxThread(SceSize args, void *argp)
{
PspUDPrx* pRx = (PspUDPrx*)argp;
pRx->ListenInOwnThread();
return 0;
}
Unfortunately, the sceNetInetRecv of the method ListenInOwnThread() does not work if i create that thread. It works fine if i don't create the thread and just call that method instead.
I presume i don't initialize the thread properly, is there some special parameter i should pass ? i tried PSP_THREAD_ATTR_USBWLAN without success.
Or maybe it's inside UdpRxThread(SceSize args, void *argp) that i don't cast properly the argp ? |
|
| Back to top |
|
 |
AudioMonster
Joined: 07 Sep 2005 Posts: 37
|
Posted: Tue Sep 27, 2005 12:20 am Post subject: C++ : Passing "this" pointer to sceKernelStartThre |
|
|
It seems my problem is about passing "this" to sceKernelStartThread.
So inside the function ListenInOwnThread() i don't have access to the real data member of that instance of my object.
in StartListening() i do
if(tmp >= 0)
{
printf("this = %x\n",(unsigned int)this);
sceKernelStartThread(tmp, sizeof(PspUDPrx*), this);
}
and in UdpRxThread() i do
PspUDPrx* pRx = (PspUDPrx*)argp;
printf("pRx = %x\n",(unsigned int)pRx);
pRx->ListenInOwnThread();
the 2 printf give a different value for the address of the instance of my object. Do i do something wrong in the way i cast ? |
|
| Back to top |
|
 |
PspPet
Joined: 30 Mar 2005 Posts: 210
|
Posted: Tue Sep 27, 2005 12:42 am Post subject: |
|
|
re: sceKernelStartThread
BTW: If you want to access any global variables (or static variables in your class) you need a smaller assembler stub that sets the GP register before calling "PspUDPrx::UdpRxThread"
The args passed between threads are a *COPY* of the data you pass to "sceKernelStartThread". Your existing code can't handle that.
Add a "&" and "*" it should work. Instead use:
sceKernelStartThread(tmp, sizeof(PspUDPrx*), &this);
and:
PspUDPrx* pRx = *(*PspUDPrx*)argp;
Ideally put them into a structure |
|
| Back to top |
|
 |
AudioMonster
Joined: 07 Sep 2005 Posts: 37
|
Posted: Tue Sep 27, 2005 1:38 am Post subject: |
|
|
int sceKernelStartThread (SceUID thid, SceSize args, void* argp)
Aaah so sceKernelStartThread actually contains a buffer of size |
|
| Back to top |
|
 |
mrbrown
Joined: 17 Jan 2004 Posts: 1536
|
Posted: Tue Sep 27, 2005 1:42 am Post subject: |
|
|
| PspPet wrote: | re: sceKernelStartThread
BTW: If you want to access any global variables (or static variables in your class) you need a smaller assembler stub that sets the GP register before calling "PspUDPrx::UdpRxThread" |
GP is set by the kernel before executing the app (it needs no assistance from crt0). GP is shared across the entire program. GP only needs to be saved and restored if calling into a custom PRX that also uses GP (and this is usually done by the PRX itself). |
|
| Back to top |
|
 |
AudioMonster
Joined: 07 Sep 2005 Posts: 37
|
Posted: Tue Sep 27, 2005 1:42 am Post subject: |
|
|
Opps sorry for last post.
int sceKernelStartThread (SceUID thid, SceSize args, void* argp)
Aaah so the thread actually contains a buffer of size args and do an actually copy of argp into that internal buffer and pass it to the thread function ? That's very unusual ! :-P
Well, so i guess i was receiving the first 4 bytes of my object and not the actual address...
BTW: If you want to access any global variables (or static variables in your class) you need a smaller assembler stub that sets the GP register before calling "PspUDPrx::UdpRxThread"
What do you mean by that ? |
|
| Back to top |
|
 |
AudioMonster
Joined: 07 Sep 2005 Posts: 37
|
Posted: Tue Sep 27, 2005 1:51 am Post subject: |
|
|
sceKernelStartThread(tmp, sizeof(PspUDPrx*), &this);
PspUDPrx.cpp:163: error: invalid lvalue in unary '&'
It seems like i need to use and intermediate variable.
PspUDPrx* pThis = this;
sceKernelStartThread(tmp, sizeof(PspUDPrx*), &pThis);
Any direct way to do this ? |
|
| Back to top |
|
 |
mrbrown
Joined: 17 Jan 2004 Posts: 1536
|
Posted: Tue Sep 27, 2005 1:58 am Post subject: |
|
|
| AudioMonster wrote: | BTW: If you want to access any global variables (or static variables in your class) you need a smaller assembler stub that sets the GP register before calling "PspUDPrx::UdpRxThread"
What do you mean by that ? |
Read my post, you can pretty much ignore that. But if you want optimized access to global variables, pass -G8 instead of -G0 on the command line. |
|
| Back to top |
|
 |
|