Avoiding 'new' where possible; more dilligent deletes

This commit is contained in:
Jaidyn Ann 2021-02-21 13:16:35 -06:00
parent bd358362f4
commit eef99bb569
15 changed files with 120 additions and 78 deletions

View File

@ -8,9 +8,16 @@ Important Features:
Important improvements: Important improvements:
* Stop locking during updates
* Stop memory accumulation
* A few MB accumulate on every update
* ime it's than .1 MB per feed― but if you have several feeds, it can
accumulate to a hefty sum after some time. In my case, with ~40 feeds
and updates every 30 minutes, it got to about 200MB after a week or
so.
* _Huge_ problem, but I haven't had luck figuring it out yet…
* Proper queue list (see Multiple downloads at once?) * Proper queue list (see Multiple downloads at once?)
* No hardcoded paths * No hardcoded paths
* Remove unnecessary `new`-- make sure to delete everything
* General input sanitization * General input sanitization
* File error-handling * File error-handling
* e.g., Utils.cpp's userFileError * e.g., Utils.cpp's userFileError

View File

@ -25,19 +25,6 @@
#include "Util.h" #include "Util.h"
int
main(int argc, char** argv)
{
srand(time(0));
installMimeTypes();
App* app = new App();
app->Run();
app->fPreferences->Save();
return 0;
}
App::App() : BApplication("application/x-vnd.Pogger") App::App() : BApplication("application/x-vnd.Pogger")
{ {
fPreferences = new Preferences; fPreferences = new Preferences;
@ -49,14 +36,14 @@ App::App() : BApplication("application/x-vnd.Pogger")
fNotifier = new Notifier(); fNotifier = new Notifier();
fFeedController = new FeedController(); fFeedController = new FeedController();
BMessage* updateMessage = new BMessage(kUpdateSubscribed); BMessage updateMessage(kUpdateSubscribed);
int64 interval = fPreferences->UpdateInterval(); int64 interval = fPreferences->UpdateInterval();
int32 count = -1; int32 count = -1;
if (interval == -1) if (interval == -1)
count = 0; count = 0;
// else // else
// MessageReceived(updateMessage); // MessageReceived(&updateMessage);
fUpdateRunner = new BMessageRunner(this, updateMessage, interval, count); fUpdateRunner = new BMessageRunner(this, updateMessage, interval, count);
} }
@ -106,6 +93,19 @@ App::MessageReceived(BMessage* msg)
} }
bool
App::QuitRequested()
{
delete fUpdateRunner, fFeedController, fNotifier;
if (fMainWindow->Lock())
fMainWindow->Quit();
fPreferences->Save();
delete fPreferences;
return true;
}
void void
App::ArgvReceived(int32 argc, char** argv) App::ArgvReceived(int32 argc, char** argv)
{ {
@ -121,10 +121,10 @@ App::ArgvReceived(int32 argc, char** argv)
else if (BUrl(argv[i]).IsValid()) { else if (BUrl(argv[i]).IsValid()) {
Feed* newFeed = new Feed(BUrl(argv[i])); Feed* newFeed = new Feed(BUrl(argv[i]));
BMessage* enqueue = new BMessage(kEnqueueFeed); BMessage enqueue = BMessage(kEnqueueFeed);
enqueue->AddData("feeds", B_RAW_TYPE, (void*)newFeed, sizeof(Feed)); enqueue.AddData("feeds", B_RAW_TYPE, (void*)newFeed, sizeof(Feed));
MessageReceived(enqueue); MessageReceived(&enqueue);
} }
} }
RefsReceived(&refMsg); RefsReceived(&refMsg);
@ -216,3 +216,15 @@ App::_OpenSourceFile(BMessage* refMessage)
const char* configPath = "/boot/home/config/settings/Pogger/"; const char* configPath = "/boot/home/config/settings/Pogger/";
int
main(int argc, char** argv)
{
srand(time(0));
installMimeTypes();
App* app = new App();
app->Run();
return 0;
}

View File

@ -20,8 +20,11 @@ class Notifier;
class App : public BApplication class App : public BApplication
{ {
public: public:
App(void); App();
void MessageReceived(BMessage* msg); void MessageReceived(BMessage* msg);
bool QuitRequested();
void ArgvReceived(int32 argc, char** argv); void ArgvReceived(int32 argc, char** argv);
void RefsReceived(BMessage* message); void RefsReceived(BMessage* message);

View File

@ -75,8 +75,7 @@ AtomFeed::RootParse(tinyxml2::XMLElement* xfeed)
void void
AtomFeed::EntryParse(tinyxml2::XMLElement* xentry) AtomFeed::EntryParse(tinyxml2::XMLElement* xentry)
{ {
Entry* newEntry = (Entry*)malloc(sizeof(Entry)); Entry* newEntry = new Entry();
newEntry = new Entry();
tinyxml2::XMLElement* xcontent = xentry->FirstChildElement("content"); tinyxml2::XMLElement* xcontent = xentry->FirstChildElement("content");
tinyxml2::XMLElement* xmedia = xentry->FirstChildElement("media:group"); tinyxml2::XMLElement* xmedia = xentry->FirstChildElement("media:group");

View File

@ -23,32 +23,36 @@ Entry::Entry()
} }
Entry::~Entry()
{}
bool bool
Entry::Filetize(BDirectory outDir) Entry::Filetize(BDirectory outDir)
{ {
BFile* file = new BFile(title.String(), B_READ_WRITE); BFile file(title.String(), B_READ_WRITE);
time_t tt_date = date.Time_t(); time_t tt_date = date.Time_t();
outDir.CreateFile(title.String(), file); outDir.CreateFile(title.String(), &file);
BString betype = BString("text/x-feed-entry"); BString betype = BString("text/x-feed-entry");
file->WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, betype.String(), file.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, betype.String(),
betype.CountChars() + 1); betype.CountChars() + 1);
file->WriteAttr("Feed:name", B_STRING_TYPE, 0, file.WriteAttr("Feed:name", B_STRING_TYPE, 0,
title.String(), title.CountChars()); title.String(), title.CountChars());
file->WriteAttr("Feed:description", B_STRING_TYPE, 0, file.WriteAttr("Feed:description", B_STRING_TYPE, 0,
description.String(), description.CountChars()); description.String(), description.CountChars());
file->WriteAttr("Feed:source", B_STRING_TYPE, 0, file.WriteAttr("Feed:source", B_STRING_TYPE, 0,
feedTitle.String(), feedTitle.CountChars()); feedTitle.String(), feedTitle.CountChars());
file->WriteAttr("META:url", B_STRING_TYPE, 0, postUrl.String(), file.WriteAttr("META:url", B_STRING_TYPE, 0, postUrl.String(),
postUrl.CountChars()); postUrl.CountChars());
if (date != NULL) { if (date != NULL) {
file->WriteAttr("Feed:when", B_TIME_TYPE, 0, &tt_date, sizeof(time_t)); file.WriteAttr("Feed:when", B_TIME_TYPE, 0, &tt_date, sizeof(time_t));
} }
file->Write(content.String(), content.Length()); file.Write(content.String(), content.Length());
return false; return false;
} }

View File

@ -18,6 +18,7 @@ class Entry {
public: public:
Entry(); Entry();
~Entry();
bool Filetize(BDirectory outDir); bool Filetize(BDirectory outDir);

View File

@ -86,6 +86,13 @@ Feed::Feed()
} }
Feed::~Feed()
{
for (int i = entries.CountItems(); i >= 0; i--)
delete ((Entry*)entries.RemoveItem(i));
}
void void
Feed::Parse() Feed::Parse()
{ {

View File

@ -27,6 +27,8 @@ public:
Feed(Feed*); Feed(Feed*);
Feed(); Feed();
~Feed();
virtual void Parse(); virtual void Parse();
BList GetEntries(); BList GetEntries();

View File

@ -60,10 +60,10 @@ FeedController::MessageReceived(BMessage* msg)
{ {
BList subFeeds = SubscribedFeeds(); BList subFeeds = SubscribedFeeds();
for (int i = 0; i < subFeeds.CountItems(); i++) { for (int i = 0; i < subFeeds.CountItems(); i++) {
BMessage* getFeed = new BMessage(kEnqueueFeed); BMessage getFeed(kEnqueueFeed);
getFeed->AddData("feeds", B_RAW_TYPE, subFeeds.ItemAt(i), getFeed.AddData("feeds", B_RAW_TYPE, subFeeds.ItemAt(i),
sizeof(Feed)); sizeof(Feed));
((App*)be_app)->MessageReceived(getFeed); ((App*)be_app)->MessageReceived(&getFeed);
} }
break; break;
} }
@ -83,10 +83,10 @@ FeedController::MessageReceived(BMessage* msg)
if (((Feed*)data)->IsUpdated() == true) if (((Feed*)data)->IsUpdated() == true)
send_data(fParseThread, msg->what, data, size); send_data(fParseThread, msg->what, data, size);
else { else {
BMessage* complete = new BMessage(kParseComplete); BMessage complete(kParseComplete);
complete->AddString("feed_name", ((Feed*)data)->GetTitle()); complete.AddString("feed_name", ((Feed*)data)->GetTitle());
complete->AddInt32("entry_count", 0); complete.AddInt32("entry_count", 0);
((App*)be_app)->MessageReceived(complete); ((App*)be_app)->MessageReceived(&complete);
} }
i++; i++;
} }
@ -118,25 +118,25 @@ int32
FeedController::_DownloadLoop(void* ignored) FeedController::_DownloadLoop(void* ignored)
{ {
thread_id sender; thread_id sender;
Feed* feedBuffer = new Feed(); Feed* feedBuffer = (Feed*)malloc(sizeof(Feed));
while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) { while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) {
std::cout << "Downloading feed from " std::cout << "Downloading feed from "
<< feedBuffer->GetXmlUrl().UrlString() << "\n"; << feedBuffer->GetXmlUrl().UrlString() << "\n";
BMessage* downloadInit = new BMessage(kDownloadStart); BMessage downloadInit = BMessage(kDownloadStart);
downloadInit->AddString("feed", feedBuffer->GetTitle()); downloadInit.AddString("feed", feedBuffer->GetTitle());
((App*)be_app)->MessageReceived(downloadInit); ((App*)be_app)->MessageReceived(&downloadInit);
if (feedBuffer->Fetch()) { if (feedBuffer->Fetch()) {
BMessage* downloaded = new BMessage(kDownloadComplete); BMessage downloaded = BMessage(kDownloadComplete);
downloaded->AddData("feeds", B_RAW_TYPE, feedBuffer, sizeof(Feed)); downloaded.AddData("feeds", B_RAW_TYPE, feedBuffer, sizeof(Feed));
((App*)be_app)->MessageReceived(downloaded); ((App*)be_app)->MessageReceived(&downloaded);
} }
else { else {
BMessage* failure = new BMessage(kDownloadFail); BMessage failure = BMessage(kDownloadFail);
failure->AddString("feed_url", feedBuffer->GetXmlUrl().UrlString()); failure.AddString("feed_url", feedBuffer->GetXmlUrl().UrlString());
((App*)be_app)->MessageReceived(failure); ((App*)be_app)->MessageReceived(&failure);
} }
} }
delete(feedBuffer); delete(feedBuffer);
@ -148,7 +148,7 @@ int32
FeedController::_ParseLoop(void* ignored) FeedController::_ParseLoop(void* ignored)
{ {
thread_id sender; thread_id sender;
Feed* feedBuffer = new Feed(); Feed* feedBuffer = (Feed*)malloc(sizeof(Feed));
while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) { while (receive_data(&sender, (void*)feedBuffer, sizeof(Feed)) != 0) {
BList entries; BList entries;
@ -162,7 +162,10 @@ FeedController::_ParseLoop(void* ignored)
feed->Parse(); feed->Parse();
entries = feed->GetNewEntries(); entries = feed->GetNewEntries();
feedTitle = feed->GetTitle(); feedTitle = feed->GetTitle();
delete(feed);
for (int i = 0; i < entries.CountItems(); i++)
((Entry*)entries.ItemAt(i))->Filetize(outDir);
delete feed;
} }
else if (feedBuffer->IsRss()) { else if (feedBuffer->IsRss()) {
RssFeed* feed = (RssFeed*)malloc(sizeof(RssFeed)); RssFeed* feed = (RssFeed*)malloc(sizeof(RssFeed));
@ -170,26 +173,26 @@ FeedController::_ParseLoop(void* ignored)
feed->Parse(); feed->Parse();
entries = feed->GetNewEntries(); entries = feed->GetNewEntries();
feedTitle = feed->GetTitle(); feedTitle = feed->GetTitle();
delete(feed);
for (int i = 0; i < entries.CountItems(); i++)
((Entry*)entries.ItemAt(i))->Filetize(outDir);
delete feed;
} }
if (feedBuffer->IsAtom() || feedBuffer->IsRss()) { if (feedBuffer->IsAtom() || feedBuffer->IsRss()) {
for (int i = 0; i < entries.CountItems(); i++) BMessage complete = BMessage(kParseComplete);
((Entry*)entries.ItemAt(i))->Filetize(outDir); complete.AddString("feed_name", feedTitle);
complete.AddInt32("entry_count", entries.CountItems());
BMessage* complete = new BMessage(kParseComplete); ((App*)be_app)->MessageReceived(&complete);
complete->AddString("feed_name", feedTitle);
complete->AddInt32("entry_count", entries.CountItems());
((App*)be_app)->MessageReceived(complete);
} }
else { else {
BMessage* failure = new BMessage(kParseFail); BMessage failure = BMessage(kParseFail);
failure->AddString("feed_url", feedUrl.UrlString()); failure.AddString("feed_url", feedUrl.UrlString());
((App*)be_app)->MessageReceived(failure); ((App*)be_app)->MessageReceived(&failure);
} }
} }
delete (feedBuffer); delete (feedBuffer);
return 0; return 0;
} }

View File

@ -29,6 +29,7 @@ class FeedController{
public: public:
FeedController(); FeedController();
~FeedController(); ~FeedController();
void MessageReceived(BMessage* msg); void MessageReceived(BMessage* msg);
static BList SubscribedFeeds(); static BList SubscribedFeeds();

View File

@ -137,11 +137,12 @@ FeedEditWindow::_SaveFeed()
fFeed->SetXmlUrl(BUrl(urlString)); fFeed->SetXmlUrl(BUrl(urlString));
fFeed->Filetize(); fFeed->Filetize();
BMessage* enqueueUpdated = new BMessage(kEnqueueFeed); BMessage edited(kFeedsEdited);
enqueueUpdated->AddData("feeds", B_RAW_TYPE, (void*)fFeed, sizeof(Feed)); BMessage enqueueUpdated(kEnqueueFeed);
enqueueUpdated.AddData("feeds", B_RAW_TYPE, (void*)fFeed, sizeof(Feed));
((App*)be_app)->MessageReceived(enqueueUpdated); ((App*)be_app)->MessageReceived(&enqueueUpdated);
((App*)be_app)->PostMessage(new BMessage(kFeedsEdited)); ((App*)be_app)->PostMessage(&edited);
Quit(); Quit();
} }
@ -150,7 +151,8 @@ void
FeedEditWindow::_DeleteFeed() FeedEditWindow::_DeleteFeed()
{ {
fFeed->Unfiletize(); fFeed->Unfiletize();
((App*)be_app)->PostMessage(new BMessage(kFeedsEdited)); BMessage edited(kFeedsEdited);
((App*)be_app)->PostMessage(&edited);
Quit(); Quit();
} }

View File

@ -13,8 +13,6 @@
#include <SeparatorView.h> #include <SeparatorView.h>
#include <StringView.h> #include <StringView.h>
#include <cstdio>
#include "App.h" #include "App.h"
#include "Feed.h" #include "Feed.h"
#include "FeedController.h" #include "FeedController.h"
@ -52,7 +50,6 @@ FeedsView::MessageReceived(BMessage* msg)
case kFeedsEditButton: case kFeedsEditButton:
{ {
_EditSelectedFeed(); _EditSelectedFeed();
_PopulateFeedList();
break; break;
} }
case kFeedsSelected: case kFeedsSelected:
@ -180,12 +177,17 @@ FeedsView::_PopulateFeedList()
BList feeds = FeedController::SubscribedFeeds(); BList feeds = FeedController::SubscribedFeeds();
int32 selected = fFeedsListView->CurrentSelection(); int32 selected = fFeedsListView->CurrentSelection();
fFeedsListView->MakeEmpty(); for (int i = fFeedsListView->CountItems(); i >= 0; i--)
delete ((FeedListItem*)fFeedsListView->RemoveItem(i));
for (int i = 0; i < feeds.CountItems(); i++) { for (int i = 0; i < feeds.CountItems(); i++) {
FeedListItem* item = new FeedListItem((Feed*)feeds.ItemAt(i)); FeedListItem* item = new FeedListItem((Feed*)feeds.ItemAt(i));
fFeedsListView->AddItem(item); fFeedsListView->AddItem(item);
} }
for (int i = feeds.CountItems(); i >= 0; i--)
delete ((Feed*)feeds.RemoveItem(i));
if (fFeedsListView->CountItems() < selected) if (fFeedsListView->CountItems() < selected)
selected = fFeedsListView->CountItems(); selected = fFeedsListView->CountItems();
fFeedsListView->Select(selected); fFeedsListView->Select(selected);

View File

@ -134,11 +134,11 @@ Notifier::_DownloadFailNotification(BString feedUrl)
void void
Notifier::_UpdateProgress() Notifier::_UpdateProgress()
{ {
BMessage* progress = new BMessage(kProgress); BMessage progress = BMessage(kProgress);
progress->AddInt32("max", fEnqueuedFeeds); progress.AddInt32("max", fEnqueuedFeeds);
progress->AddInt32("current", fFeedsInProgress); progress.AddInt32("current", fFeedsInProgress);
((App*)be_app)->MessageReceived(progress); ((App*)be_app)->MessageReceived(&progress);
if (fFeedsInProgress == 0) if (fFeedsInProgress == 0)
fEnqueuedFeeds = 0; fEnqueuedFeeds = 0;

View File

@ -59,8 +59,7 @@ RssFeed::RootParse(tinyxml2::XMLElement* xchan)
void void
RssFeed::EntryParse(tinyxml2::XMLElement* xitem) RssFeed::EntryParse(tinyxml2::XMLElement* xitem)
{ {
Entry* newEntry = (Entry*)malloc(sizeof(Entry)); Entry* newEntry = new Entry();
newEntry = new Entry();
newEntry->SetTitle(xitem->FirstChildElement("title")); newEntry->SetTitle(xitem->FirstChildElement("title"));
newEntry->SetDesc(xitem->FirstChildElement("description")); newEntry->SetDesc(xitem->FirstChildElement("description"));

View File

@ -93,7 +93,7 @@ UpdatesView::_InitInterface()
fIntervalSlider->SetHashMarkCount(26); fIntervalSlider->SetHashMarkCount(26);
fIntervalSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fIntervalSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fIntervalSlider->SetLimitLabels("Never", "24 hours"); fIntervalSlider->SetLimitLabels("Never", "24 hours");
fIntervalSlider->SetModificationMessage(new BMessage('iiii')); fIntervalSlider->SetModificationMessage(new BMessage(kIntervalChanged));
// Display current settings // Display current settings