summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/media/metadata.go2
-rw-r--r--internal/media/probe.go5
-rw-r--r--internal/media/util.go25
3 files changed, 25 insertions, 7 deletions
diff --git a/internal/media/metadata.go b/internal/media/metadata.go
index c1fa58645..6524784fd 100644
--- a/internal/media/metadata.go
+++ b/internal/media/metadata.go
@@ -75,7 +75,7 @@ func clearMetadata(ctx context.Context, filepath string) error {
// terminateExif cleans exif data from file at input path, into file
// at output path, using given file extension to determine cleaning type.
func terminateExif(outpath, inpath string, ext string) (err error) {
- var inFile *os.File
+ var inFile fileReader
var outFile *os.File
// Ensure handles
diff --git a/internal/media/probe.go b/internal/media/probe.go
index 5c07b04fb..47990eea3 100644
--- a/internal/media/probe.go
+++ b/internal/media/probe.go
@@ -22,7 +22,6 @@ import (
"encoding/binary"
"image/jpeg"
"io"
- "os"
"strings"
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
@@ -80,7 +79,7 @@ func probe(ctx context.Context, filepath string) (*result, error) {
// probeJPEG decodes the given file as JPEG and determines
// image details from the decoded JPEG using native Go code.
-func probeJPEG(file *os.File) (*result, error) {
+func probeJPEG(file fileReader) (*result, error) {
// Attempt to decode JPEG, adding back hdr magic.
cfg, err := jpeg.DecodeConfig(io.MultiReader(
@@ -129,7 +128,7 @@ func probeJPEG(file *os.File) (*result, error) {
//
// copied from github.com/disintegration/imaging
// but modified to optimize discard operations.
-func readOrientation(r *os.File) int {
+func readOrientation(r fileReader) int {
const (
markerAPP1 = 0xffe1
exifHeader = 0x45786966
diff --git a/internal/media/util.go b/internal/media/util.go
index d73206434..fbd232daa 100644
--- a/internal/media/util.go
+++ b/internal/media/util.go
@@ -24,10 +24,13 @@ import (
"io/fs"
"os"
"path"
+ "runtime"
+ "syscall"
"code.superseriousbusiness.org/gotosocial/internal/gtserror"
"codeberg.org/gruf/go-bytesize"
"codeberg.org/gruf/go-iotools"
+ "codeberg.org/gruf/go-mmap"
)
// media processing tmpdir.
@@ -82,15 +85,31 @@ func (af allowFiles) Open(name string) (fs.File, error) {
// Ffmpeg likes to read containing
// dir as '.'. Allow RO access here.
case ".":
- return openRead(file.dir)
+ return os.OpenFile(file.dir, os.O_RDONLY, 0)
}
}
return nil, os.ErrPermission
}
+// MmapThreshold defines the threshold file size (in bytes) for which
+// a call to OpenRead() will deem as big enough for a file to be worth
+// opening using an `mmap` syscall. This is a runtime initialized number
+// based on the number of available CPUs, as in concurrent conditions Go
+// can make optimizations for blocking `read` syscalls which scales with
+// the number of available goroutines it can have running at once.
+var mmapThreshold = mmap.Threshold{At: int64(runtime.NumCPU() * syscall.Getpagesize())}
+
+// fileReader is a type alias to the interface{} that
+// codeberg.org/gruf/go-mmap exposes, to make things a
+// little less visually confusing. this interfaces{}
+// abstracts away whether a (regular!) file has been
+// opened via os.OpenFile(..., RDONLY) or has been
+// mmapped into memory for access via byte slice.
+type fileReader = mmap.FileReader
+
// openRead opens the existing file at path for reads only.
-func openRead(path string) (*os.File, error) {
- return os.OpenFile(path, os.O_RDONLY, 0)
+func openRead(path string) (fileReader, error) {
+ return mmapThreshold.OpenRead(path)
}
// openWrite opens the (new!) file at path for read / writes.