Skip to content

Commit

Permalink
Fixes some deadlock conditions and more robustness
Browse files Browse the repository at this point in the history
  • Loading branch information
alexp-sssup committed May 22, 2010
1 parent dd83e05 commit 0dec69d
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 18 deletions.
1 change: 1 addition & 0 deletions TODO
Expand Up @@ -17,3 +17,4 @@ Official TODO Queue:
-) Add Named Objects to frames and not to clips
-) Support mozilla Out of process plugin mode - Waiting for multithreaded GTK support from mozilla
-) Conditional scaling of FontGlyph based on version
-) Why std::istream catches our exeptions?
6 changes: 4 additions & 2 deletions plugin-dir/plugin.cpp
Expand Up @@ -268,6 +268,8 @@ nsPluginInstance::nsPluginInstance(NPP aInstance, int16_t argc, char** argn, cha
sys->setOrigin(argv[i]);
}
}
m_sys.downloadManager=new NPDownloadManager(mInstance);
m_sys.addJob(&m_pt);
}

int nsPluginInstance::hexToInt(char c)
Expand All @@ -286,6 +288,8 @@ nsPluginInstance::~nsPluginInstance()
{
//Shutdown the system
//cerr << "instance dying" << endl;
swf_buf.destroy();
m_pt.stop();
m_sys.setShutdownFlag();
m_sys.wait();
if(m_rt)
Expand Down Expand Up @@ -399,8 +403,6 @@ NPError nsPluginInstance::SetWindow(NPWindow* aWindow)
sys=NULL;
m_sys.inputThread=m_it;
m_sys.renderThread=m_rt;
m_sys.downloadManager=new NPDownloadManager(mInstance);
m_sys.addJob(&m_pt);
}
//draw();
return TRUE;
Expand Down
30 changes: 23 additions & 7 deletions streams.cpp
Expand Up @@ -26,7 +26,7 @@

using namespace std;

sync_stream::sync_stream():head(0),tail(0),wait_notfull(false),wait_notempty(false),buf_size(1024*1024)
sync_stream::sync_stream():head(0),tail(0),wait_notfull(false),wait_notempty(false),buf_size(1024*1024),failed(false)
{
buffer=new char[buf_size];
sem_init(&mutex,0,1);
Expand All @@ -41,6 +41,13 @@ sync_stream::~sync_stream()
sem_destroy(&notempty);
}

void sync_stream::destroy()
{
failed=true;
sem_post(&notfull);
sem_post(&notempty);
}

int sync_stream::provideBuffer(int limit)
{
sem_wait(&mutex);
Expand All @@ -49,6 +56,8 @@ int sync_stream::provideBuffer(int limit)
wait_notempty=true;
sem_post(&mutex);
sem_wait(&notempty);
if(failed)
return 0;
}

int available=(tail-head+buf_size)%buf_size;
Expand Down Expand Up @@ -82,6 +91,8 @@ uint32_t sync_stream::write(char* buf, int len)
wait_notfull=true;
sem_post(&mutex);
sem_wait(&notfull);
if(failed)
return 0;
}

if((head-tail+buf_size-1)%buf_size<len)
Expand Down Expand Up @@ -120,16 +131,17 @@ zlib_filter::zlib_filter():consumed(0),available(0)
{
}

void zlib_filter::initialize()
bool zlib_filter::initialize()
{
//Should check that this is called only once
available=provideBuffer(8);
assert(available==8);
if(available!=8)
return false;
//We read only the first 8 bytes, as those are always uncompressed

//Now check the signature
if(in_buf[1]!='W' || in_buf[2]!='S')
abort();
return false;
if(in_buf[0]=='F')
compressed=false;
else if(in_buf[0]=='C')
Expand All @@ -148,13 +160,14 @@ void zlib_filter::initialize()
}
}
else
abort();
return false;

//Ok, it seems to be a valid SWF, from now, if the file is compressed, data has to be inflated

//Copy the in_buf to the out buffer
memcpy(buffer,in_buf,8);
setg(buffer,buffer,buffer+available);
return true;
}

zlib_filter::int_type zlib_filter::underflow()
Expand All @@ -167,8 +180,11 @@ zlib_filter::int_type zlib_filter::underflow()
//The first time
if(consumed==0)
{
initialize();
return (unsigned char)buffer[0];
bool ret=initialize();
if(ret)
return (unsigned char)buffer[0];
else
throw lightspark::ParseException("Not an SWF file");
}

if(!compressed)
Expand Down
4 changes: 3 additions & 1 deletion streams.h
Expand Up @@ -35,7 +35,7 @@ class zlib_filter: public std::streambuf
char buffer[4096];
int available;
virtual int provideBuffer(int limit)=0;
void initialize();
bool initialize();
protected:
char in_buf[4096];
virtual int_type underflow();
Expand All @@ -48,6 +48,7 @@ class sync_stream: public zlib_filter
{
public:
sync_stream();
void destroy();
~sync_stream();
uint32_t write(char* buf, int len);
uint32_t getFree();
Expand All @@ -62,6 +63,7 @@ class sync_stream: public zlib_filter
bool wait_notfull;
bool wait_notempty;
const int buf_size;
bool failed;
};

class zlib_file_filter:public zlib_filter
Expand Down
32 changes: 27 additions & 5 deletions swf.cpp
Expand Up @@ -56,7 +56,7 @@ extern TLSDATA SystemState* sys;
extern TLSDATA RenderThread* rt;
extern TLSDATA ParseThread* pt;

SWF_HEADER::SWF_HEADER(istream& in)
SWF_HEADER::SWF_HEADER(istream& in):valid(false)
{
in >> Signature[0] >> Signature[1] >> Signature[2];

Expand All @@ -72,7 +72,7 @@ SWF_HEADER::SWF_HEADER(istream& in)
else
{
LOG(LOG_NO_INFO,"No SWF file signature found");
abort();
return;
}
pt->version=Version;
in >> FrameSize >> FrameRate >> FrameCount;
Expand All @@ -85,9 +85,10 @@ SWF_HEADER::SWF_HEADER(istream& in)
sys->setRenderRate(frameRate);
pt->root->version=Version;
pt->root->fileLenght=FileLength;
valid=true;
}

RootMovieClip::RootMovieClip(LoaderInfo* li, bool isSys):initialized(false),frameRate(0),toBind(false)
RootMovieClip::RootMovieClip(LoaderInfo* li, bool isSys):initialized(false),parsingIsFailed(false),frameRate(0),toBind(false)
{
root=this;
sem_init(&mutex,0,1);
Expand Down Expand Up @@ -116,6 +117,15 @@ RootMovieClip::~RootMovieClip()
sem_destroy(&sem_valid_size);
}

void RootMovieClip::parsingFailed()
{
//The parsing is failed, we have no change to be ever valid
parsingIsFailed=true;
sem_post(&new_frame);
sem_post(&sem_valid_size);
sem_post(&sem_valid_rate);
}

void RootMovieClip::bindToName(const tiny_string& n)
{
assert(toBind==false);
Expand Down Expand Up @@ -404,6 +414,8 @@ void ParseThread::execute()
try
{
SWF_HEADER h(f);
if(!h.valid)
throw ParseException("Not an SWF file");
root->setFrameSize(h.getFrameSize());
root->setFrameCount(h.FrameCount);

Expand Down Expand Up @@ -455,6 +467,8 @@ void ParseThread::execute()
}
catch(LightsparkException& e)
{
LOG(LOG_ERROR,"Exception in ParseThread " << e.what());
root->parsingFailed();
sys->setError(e.cause);
}
pt=NULL;
Expand All @@ -464,8 +478,8 @@ void ParseThread::execute()

void ParseThread::threadAbort()
{
//TODO: implement
::abort();
//Tell the our RootMovieClip that the parsing is ending
root->parsingFailed();
}

void ParseThread::wait()
Expand Down Expand Up @@ -1484,6 +1498,8 @@ void RootMovieClip::Render()

sem_post(&sem_frames);
sem_wait(&new_frame);
if(parsingIsFailed)
return;
sem_wait(&sem_frames);
}

Expand Down Expand Up @@ -1549,6 +1565,7 @@ void RenderThread::commonGLInit(int width, int height, unsigned int t2[3])
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

while(glGetError()!=GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);

glBindTexture(GL_TEXTURE_2D,t2[1]);
Expand Down Expand Up @@ -1582,6 +1599,11 @@ void RenderThread::commonGLInit(int width, int height, unsigned int t2[3])
if(status != GL_FRAMEBUFFER_COMPLETE)
{
LOG(LOG_ERROR,"Incomplete FBO status " << status << "... Aborting");
while(err!=GL_NO_ERROR)
{
LOG(LOG_ERROR,"GL errors during initialization: " << err);
err=glGetError();
}
::abort();
}
}
Expand Down
8 changes: 5 additions & 3 deletions swf.h
Expand Up @@ -71,7 +71,7 @@ class SWF_HEADER
RECT FrameSize;
UI16 FrameRate;
UI16 FrameCount;
public:
bool valid;
SWF_HEADER(std::istream& in);
const RECT& getFrameSize(){ return FrameSize; }
};
Expand All @@ -82,11 +82,12 @@ class RootMovieClip: public MovieClip, public ITickJob
friend class ParseThread;
protected:
sem_t mutex;
//Semaphore to wait for new frames to be available
sem_t new_frame;
bool initialized;
tiny_string origin;
private:
//Semaphore to wait for new frames to be available
sem_t new_frame;
bool parsingIsFailed;
RGB Background;
std::list < DictionaryTag* > dictionary;
//frameSize and frameRate are valid only after the header has been parsed
Expand Down Expand Up @@ -118,6 +119,7 @@ friend class ParseThread;
void commitFrame(bool another);
void revertFrame();
void Render();
void parsingFailed();
bool getBounds(number_t& xmin, number_t& xmax, number_t& ymin, number_t& ymax) const;
void bindToName(const tiny_string& n);
void initialize();
Expand Down

0 comments on commit 0dec69d

Please sign in to comment.