On Thursday, January 24, 2008, 17:14 Przemyslaw Czerpak
<[EMAIL PROTECTED]> wrote:
The C level socket API is used in client part, because the RDD is
written on C. I don't see serious problem here, too, because I'm sure
that in the case of necessity appropriate separated parts can be easily
adopted.
PC> So how it will work with compressed socket when we add native
PC> support for stream compression?
Just borrowing appropriate piece of code. I hope that such important
additions won't come every month :).
PC> And what if Harbour socket will not have usable OS handle at all
PC> on some platforms? What if it will be necessary to hide some
PC> OS dependent differences? F.e. select() works a little bit different
PC> in MS-Windows then in *nixes. Even between *nixes there are some
PC> important differences in this function. Do you know these differences?
No. But I tested my code under both XP and Linux and didn't find any
difference. Maybe, I didn't dig deeply enough, though.
PC> Can you tell me what functionality is necessary for you?
See below.
PC> If it will be portable then we will add it to hbinet.c.
PC> There is absolutely no reason to make hb_inetSocketFinalize
PC> public until we want to keep sockets internals 3-rd party
PC> code independent and easy expandable.
So, you confirm that hbinet.c can't be extended by 3-rd party
libraries and if someone need any changes or additions, he have to
modify the hbinet.c. And what if this changes aren't fully portable or
suitable for general use, but satisfy his specific needs ? Isn't this a
limitation, too ?
The second is that I don't understand why hb_parptrGC(),
hb_inetSocketFinalize() are used instead of usual hb_parptr() and how to
work with them, I found it more easy for me to rewrite appropiate parts
of code than dig in it :).
PC> The answer is very simple. .prg code should protect against low level
PC> errors like GPF. hb_parptrGC() validate if given pointer is a pointer
PC> to valid socket structure. hb_parptr() will also work but it will accept
PC> all possible pointer items not only these one which point to socket
PC> structure. Look at HWGUI. There is no validation at all so user can pass
PC> wrong pointers or handles to functions which will accept them and later
PC> GPF. Such code is unsafe. We should always try to write code as safe
PC> as possible.
You are right. Harbour's rtl is written for general use and this code
may be used in any kinds of applications, including those, where this
kind of safety is important - I mean, first of all, pieces of code,
which are intended for executing by some server.
In case of common desktop applications it is, IMO, isn't important.
Imagine, that programmer made a mistake and pass some bad word :)
instead of a handle to a function. Only his desktop application will
crash and after some time of hunting he will find that mistake. And,
probably, in case of GPF it will be more easy to identify the mistake
than if the GPF doesn't occur and he get some 'strange' application
behavior. That's why, for example, I don't worry about such things in
HwGUI - as any other GUI library, it is intended for desktop applications.
In the case of rdd for the db server it isn't an issue at all, because
the socket handle is hidden in workarea structure.
PC> As I said it's not necessary at all and so far you haven't answer
PC> why you need it. Again, please tell me which additional functionality
PC> is necessary for you and I'll add them to hbinet.c.
Ok. Below are the functions I've added:
static fd_set rd_fds, active_fds;
static unsigned int rd_maxfd;
HB_FUNC( HB_IP_RFD_SET )
{
HB_SOCKET_T hSocket = (HB_SOCKET_T)hb_parnl(1);
if( !hSocket )
{
return;
}
HB_SOCKET_ZERO_ERROR();
FD_SET( hSocket, &rd_fds );
rd_maxfd = ( rd_maxfd > hSocket )? rd_maxfd : hSocket;
}
HB_FUNC( HB_IP_RFD_ZERO )
{
FD_ZERO( &rd_fds );
rd_maxfd = 0;
}
HB_FUNC( HB_IP_RFD_CLR )
{
HB_SOCKET_T hSocket = (HB_SOCKET_T)hb_parnl(1);
FD_CLR( hSocket, &rd_fds );
}
HB_FUNC( HB_IP_RFD_SELECT )
{
struct timeval tv = {0,0};
int iTimeOut;
if( hb_pcount() == 1 )
{
iTimeOut = hb_parni( 1 );
tv.tv_sec = iTimeOut / 1000;
tv.tv_usec = (iTimeOut % 1000) * 1000;
}
active_fds = rd_fds;
iTimeOut = select( rd_maxfd + 1, &active_fds, NULL, NULL, &tv);
hb_retni( iTimeOut );
}
HB_FUNC( HB_IP_RFD_ISSET )
{
HB_SOCKET_T hSocket = (HB_SOCKET_T)hb_parnl(1);
hb_retl( FD_ISSET( hSocket,&active_fds ) );
}
I know that this code isn't proper for general use, because it uses
one static rd_fds and, so this set of functions can't be used for
selecting concurrently from two sets of sockets. But it fully satisfies
my needs - at least now.
Other small change is that I've added 3'rd value of iMode to read and
send functions - to avoid the call of hb_selectReadSocket(), because I
check the socket before calling send() and receive() every time and
don't need an additional checking.
Regards,
Alexander
http://kresin.belgorod.su
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour