VNC-151 Fix crash

This commit is contained in:
El 2026-05-01 23:04:00 +03:00
parent fdefd2c2d2
commit a96f45b51c
No known key found for this signature in database
GPG key ID: EB3F4C9EA29CDE59
5 changed files with 55 additions and 17 deletions

View file

@ -35,13 +35,15 @@ namespace network {
// from main thread
void mainUpdateScreen(rfb::PixelBuffer *pb);
void lockScreenshots();
void unlockScreenshots();
void mainUpdateBottleneckStats(const char userid[], const char stats[]);
void mainClearBottleneckStats(const char userid[]);
void mainUpdateServerFrameStats(uint8_t changedPerc, uint32_t all,
uint32_t jpeg, uint32_t webp, uint32_t analysis,
uint32_t jpegarea, uint32_t webparea,
uint16_t njpeg, uint16_t nwebp,
uint16_t enc, uint16_t scale, uint16_t shot,
uint16_t enc, uint16_t scale,
uint16_t w, uint16_t h);
void mainUpdateClientFrameStats(const char userid[], uint32_t render, uint32_t all,
uint32_t ping);

View file

@ -60,7 +60,11 @@ GetAPIMessager::GetAPIMessager(const char *passwdfile_): passwdfile(passwdfile_)
ownerConnected(0), activeUsers(0),
sessionsInfo( "{\"users\":[]}"){
pthread_mutex_init(&screenMutex, NULL);
pthread_mutexattr_t screenAttr;
pthread_mutexattr_init(&screenAttr);
pthread_mutexattr_settype(&screenAttr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&screenMutex, &screenAttr);
pthread_mutexattr_destroy(&screenAttr);
pthread_mutex_init(&userMutex, NULL);
pthread_mutex_init(&statMutex, NULL);
pthread_mutex_init(&frameStatMutex, NULL);
@ -71,11 +75,19 @@ GetAPIMessager::GetAPIMessager(const char *passwdfile_): passwdfile(passwdfile_)
// from main thread
void GetAPIMessager::mainUpdateScreen(rfb::PixelBuffer *pb_) {
if (pthread_mutex_trylock(&screenMutex))
return;
pb = pb_;
}
void GetAPIMessager::lockScreenshots() {
pthread_mutex_lock(&screenMutex);
screenW = screenH = 0;
screenHash = 0;
cachedW = cachedH = cachedQ = 0;
cachedJpeg.clear();
}
void GetAPIMessager::unlockScreenshots() {
pthread_mutex_unlock(&screenMutex);
}
@ -101,7 +113,7 @@ void GetAPIMessager::mainUpdateServerFrameStats(uint8_t changedPerc,
uint32_t all, uint32_t jpeg, uint32_t webp, uint32_t analysis,
uint32_t jpegarea, uint32_t webparea,
uint16_t njpeg, uint16_t nwebp,
uint16_t enc, uint16_t scale, uint16_t shot,
uint16_t enc, uint16_t scale,
uint16_t w, uint16_t h) {
if (pthread_mutex_lock(&frameStatMutex))
@ -118,7 +130,6 @@ void GetAPIMessager::mainUpdateServerFrameStats(uint8_t changedPerc,
serverFrameStats.nwebp = nwebp;
serverFrameStats.enc = enc;
serverFrameStats.scale = scale;
serverFrameStats.shot = shot;
serverFrameStats.w = w;
serverFrameStats.h = h;
@ -164,11 +175,9 @@ void GetAPIMessager::mainUpdateSessionsInfo(std::string newSessionsInfo)
uint8_t *GetAPIMessager::netGetScreenshot(uint16_t w, uint16_t h,
const uint8_t q, const bool dedup,
uint32_t &len, uint8_t *staging) {
unsigned shottime = 0;
int stride;
if (!pb)
return nullptr;
TRACE_STOPWATCH(shotstart);
uint8_t *ret = nullptr;
len = 0;
@ -176,6 +185,11 @@ uint8_t *GetAPIMessager::netGetScreenshot(uint16_t w, uint16_t h,
if (pthread_mutex_lock(&screenMutex))
return nullptr;
if (!pb) {
pthread_mutex_unlock(&screenMutex);
return nullptr;
}
const rdr::U8 *buf = pb->getBuffer(pb->getRect(), &stride);
if (pb->width() != screenW || pb->height() != screenH) {
@ -279,6 +293,12 @@ uint8_t *GetAPIMessager::netGetScreenshot(uint16_t w, uint16_t h,
pthread_mutex_unlock(&screenMutex);
shottime = msSince(&shotstart);
if (!pthread_mutex_lock(&frameStatMutex)) {
serverFrameStats.shot = shottime;
pthread_mutex_unlock(&frameStatMutex);
}
return ret;
}

View file

@ -507,6 +507,10 @@ void VNCServerST::setPixelBuffer(PixelBuffer* pb_, const ScreenSet& layout)
renderedCursorInvalid = true;
add_changed(pb->getRect());
if (apimessager) {
apimessager->mainUpdateScreen(pb);
}
// Make sure that we have at least one screen
if (screenLayout.num_screens() == 0)
screenLayout.add_screen(Screen(0, 0, 0, pb->width(), pb->height(), 0));
@ -1104,12 +1108,7 @@ void VNCServerST::writeUpdate()
}
DEBUG_STOPWATCH_PRINT_US(slog, perm_check);
unsigned shottime = 0;
if (apimessager) {
TRACE_STOPWATCH(shotstart);
apimessager->mainUpdateScreen(pb);
shottime = msSince(&shotstart);
trackingFrameStats = 0;
checkAPIMessages(apimessager, trackingFrameStats, trackingClient);
}
@ -1178,7 +1177,7 @@ void VNCServerST::writeUpdate()
analysisMs,
jpegstats.area, webpstats.area,
jpegstats.rects, webpstats.rects,
enctime, scaletime, shottime,
enctime, scaletime,
pb->getRect().width(),
pb->getRect().height());
} else {
@ -1372,3 +1371,15 @@ void VNCServerST::notifyUserAction(const VNCSConnectionST* newConnection, std::s
logNotification.append( std::to_string(notificationsSent) + " clients");
slog.info("%s", logNotification.c_str());
}
void VNCServerST::lockScreenBuffer() const {
if (apimessager) {
apimessager->lockScreenshots();
}
}
void VNCServerST::unlockScreenBuffer() const {
if (apimessager) {
apimessager->unlockScreenshots();
}
}

View file

@ -205,6 +205,8 @@ namespace rfb {
enum UserActionType {Join, Leave};
void notifyUserAction(const VNCSConnectionST* newConnection, std::string& user_name, const UserActionType action_type);
void lockScreenBuffer() const;
void unlockScreenBuffer() const;
protected:

View file

@ -126,6 +126,8 @@ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride_)
{
ScreenSet layout;
server->lockScreenBuffer();
width_ = w;
height_ = h;
@ -147,6 +149,7 @@ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride_)
layout = ::computeScreenLayout(&outputIdMap);
server->setPixelBuffer(this, layout);
server->unlockScreenBuffer();
}
void XserverDesktop::refreshScreenLayout()