sslug-teknik team mailing list archive
-
sslug-teknik team
-
Mailing list archive
-
Message #07588
Re: Bedre browser
Mads Bondo Dydensborg wrote:
>
> On Sat, 8 May 1999, Anders S. Johansen wrote:
>
> > root wrote:
> > > Men måske er det på maskiner med lavere CPU kraft at den hænger, min er en
> > > PII-300, 128 mb RH6.0
> > > jeg har oplevet at NS hænger meget på en P75
> >
> > Hmmm. PPro, 200MhZ, 128Mb ram, ISDN, RH 6.0 og RH5.1.
> >
> > Ikke maskinens muskler det handler om :)
>
> Well. Hvis der er deadlocks, som følge af tidsting, kunne maskinens styrke
> egentlig godt have noget at sige, mht. frekvensen af fejl man oplever. Men
> ellers har du ret.
Ifølge et indlæg på l-k, så er det dels et tidsrelateret spørgsmål. Kig
i arkivet efter uge 4, jan 1999, der er en tråd med subject "Kernel OK,
netscape buggy" med en del diskussion. Jeg har vedlagt et patch som en
person i denne tråd havde lavet. Patchet oversættes til at shared
library, og vha. LD_PRELOAD overskriver man så read/write og pipe
kaldene. Det er et temmelig skummelt hack, og skulle vist resultere i at
man ikke kunne klikke på links efter et stykke tid. Derudover skulle det
af uransagelige årsager betyde 2-3 gange hurtigere sidevisning,
ihvertfald på en hurtig forbindelse. Problemet ligger i at netscape
bruger en blokerende pipe til noget synkronisering/kommunikation imellem
de 2+ processer, hvor det så går galt på en eller anden måde.
Mvh Morten
#include <dlfcn.h>
#include <unistd.h>
#include <limits.h>
/* This is a netscape bug workaround. Search for a pipe,
where only 1 byte strings \0372 are written to the write
end and only 1 byte strings are requested back. Count
the difference and fake any writes that would cause
an overflow of the pipe and corresponding reads.
This is a really dirty hack with almost no error checking
and relying on the netscape's behaviour.
Compile with
gcc -c nspipepatch.c
ld -shared -o libnspipepatch.so -ldl nspipepatch.o
and add
LD_PRELOAD=<path>/libnspipepatch.so
to your netscape starting script.
(C) 1999 Stanislav Meduna <stano@xxxxxxxxxxxxxxxxx>
There is absolutely NO WARRANTY. The use and distribution
is completely free
*/
/* The magic netscape char flowing through the pipe */
#define MAGIC ((unsigned char) '\372')
/* libc handle for dlsym */
static void *dlhdl=0;
/* pointers to overloaded functions */
static int (*pipe_fp)(int [2])=0;
static ssize_t (*write_fp)(int, const void *, size_t)=0;
static ssize_t (*read_fp)(int, void *, size_t)=0;
static int (*close_fp)(int)=0;
/* we keep the info about our descriptors here */
static struct nshack_pipe_t
{
/* If this is a pipe that could be our one,
mark both ends here. If we shouldn't touch
the descriptor, enter -1 here
*/
int read_end, write_end;
/* The difference between writes and reads,
maintained on the write end
*/
int diff;
/* Number of faked writes, maintained on the write end */
int faked;
} fdflags[256];
/* Mark the descriptors as unused or not of our interest */
static void clearfd(int fd)
{
fdflags[fd].read_end = fdflags[fd].write_end = -1;
fdflags[fd].diff = fdflags[fd].faked = 0;
}
/* Clear both ends */
static void clearboth(int fd)
{
int rd = fdflags[fd].read_end;
int wr = fdflags[fd].write_end;
if (rd >= 0)
clearfd(rd);
if (wr >= 0)
clearfd(wr);
}
/* Init the pointers to overloaded functions */
static void initptrs()
{
int i;
dlhdl = dlopen("/lib/libc.so.6", RTLD_NOW);
if (! dlhdl)
exit(99);
pipe_fp = dlsym(dlhdl, "pipe");
write_fp = dlsym(dlhdl, "write");
read_fp = dlsym(dlhdl, "read");
close_fp = dlsym(dlhdl, "close");
if (! pipe_fp || ! write_fp || ! read_fp || ! close_fp)
exit(99);
for (i=0; i < sizeof(fdflags)/sizeof(fdflags[0]); i++)
clearfd(i);
}
/* Unload the library */
void _fini()
{
if (dlhdl)
dlclose(dlhdl);
}
/* Overloaded pipe - mark the fresh pipes */
int pipe(int fd[2])
{
int res;
if (! pipe_fp)
initptrs();
res = (*pipe_fp)(fd);
if (! res)
{
/* This could be our pipe - watch it during read/write */
fdflags[fd[0]].read_end = fdflags[fd[1]].read_end = fd[0];
fdflags[fd[0]].write_end = fdflags[fd[1]].write_end= fd[1];
fdflags[fd[0]].diff = fdflags[fd[1]].faked = 0;
}
return res;
}
/* Overloaded write */
ssize_t write(int fd, const void *buf, size_t cnt)
{
int res=0;
if (! write_fp)
initptrs();
if (cnt != 1 || *(unsigned char *)buf != MAGIC)
clearboth(fd); /* This is not our pipe - magic not seen */
if (fd == fdflags[fd].write_end)
{
/* This is the write end of a watched pipe */
fdflags[fd].diff++;
/* Play safe - reduce the allowed difference
to guard against off-by-one errors and
similar :-)
*/
if (fdflags[fd].diff >= PIPE_BUF-64)
{
/* We fake the write */
fdflags[fd].faked++;
res = 1;
}
else
res = (*write_fp)(fd, buf, cnt);
}
else
res = (*write_fp)(fd, buf, cnt);
return res;
}
/* Overloaded read */
ssize_t read(int fd, void *buf, size_t cnt)
{
int res;
int watch=0;
if (! read_fp)
initptrs();
if (fd == fdflags[fd].read_end)
{
if (cnt == 1)
watch = 1;
else
clearboth(fd); /* The true one always wants one char only */
/* This is the read end of a watched pipe */
if (watch && fdflags[fdflags[fd].write_end].faked)
{
/* Faked writes exist - compensate with faked reads */
fdflags[fdflags[fd].write_end].faked--;
fdflags[fdflags[fd].write_end].diff--;
*((unsigned char *) buf) = MAGIC;
return 1;
}
}
/* Do the real read */
res = (*read_fp)(fd, buf, cnt);
if (watch && res == 1)
{
/* If we watch the pipe and the read was successfull,
use the read value to make sure this is THE pipe.
*/
if (*((unsigned char *) buf) == MAGIC)
fdflags[fd].diff--;
else
clearboth(fd);
}
return res;
}
/* Overloaded close (we want to be at least a bit correct) */
int close(int fd)
{
if (! close_fp)
initptrs();
if (fd == fdflags[fd].read_end || fd == fdflags[fd].write_end)
clearboth(fd);
return (*close_fp)(fd);
}
References